java - Lucene中Field和StringField有什么区别?

标签 java lucene

我正在 lucene 索引中搜索完全匹配的文档标题。为了实现这一目标,我有以下两种替代方法来为将被索引的文档创建字段。

方法一:

FieldType _contentFieldType = new FieldType();
_contentFieldType.setIndexed(true);
_contentFieldType.setStored(true);

Document doc = new Document();
doc.add(new Field("content", getContent(), _contentFieldType));
writer.addDocument(doc);

方法 2:

Document doc = new Document();
doc.add(new StringField("content", getContent(), Store.YES));
writer.addDocument(doc);

然后我使用 TermQuery 创建查询并在 lucene 索引中搜索,但如果我使用第一种方法,我不会得到任何结果。第二个方法对我来说工作得很好。

Query query = new TermQuery(new Term(searchQuery.fields().get(0), searchQuery.queryText()));
indexSearcher.search(query, Math.max(1, collector.getTotalHits()));

文档标题示例:文档标题实际上是文档的主题,是主题的分层路径。

Top/Arts/Animation/Audio
Top/Arts/Animation/Collectibles
Top/Arts/Animation/Stop-Motion
Top/Arts/Animation/Festivals
Top/Arts/Animation/News_and_Media
Top/Arts/Animation/Chats_and_Forums
Top/Arts/Animation/Training
Top/Arts/Animation/Voice_Actors
Top/Arts/Animation/Artists

比如说,我想搜索Top/Arts/Animation/Training。我需要精确的字符串匹配,因此我使用了 TermQuery

我阅读了文档并了解了 Field 和 StringField。因此,如果 Store.Yes 作为参数传递,则 StringField 会被索引但不会被分析。但我的问题是,由于我在方法 1 中对 Field 使用 setIndexed(true)setStored(true) ,为什么我不这样做从方法 1 中得到类似的结果吗?是因为如果我使用 Field 会执行一些额外的事情还是因为使用 TermQuery ?使这两种方法不同的主要因素是什么?请帮助我理解它们的区别。

谢谢!

最佳答案

所以这就是我认为正在发生的事情。

您在第一种方法中使用了分析器来索引哪些小写输入标记。

例如Top/Arts/Animation/Training这将存储如下

top/Arts/animation/training

现在,当您使用TERMQUERY 进行搜索时,termquery 实际上会搜索确切的字符串。即 Top/Arts/Animation/Training 由于索引中的小写而不会匹配任何内容。

我们来谈谈第二种方法。由于您使用了 StringField,因此不会分析字段并将按原样存储。即您的索引在 StringField 情况下包含以下内容

Top/Arts/Animation/Training

现在,当您使用 TermQuery 进行搜索时,这将匹配,因为它是按原样存储的。

以第一种方法获得结果

使用 QueryParser 构建查询,而不是使用 TermQuery 使用索引时使用的相同分析器。

阅读此处了解 TERMQUERYQUERYPARSER 之间的区别

what is the difference between TermQuery and QueryParser in Lucene 6.0?

编辑

存储只是意味着原始字段值存储在索引中。以便在返回搜索结果的同时也能返回。搜索发生在索引上,而不是存储的值上。存储属性背后的原因是 lucene “分析”或将输入数据转换为更有效的形式,以实现更快、更相关的搜索(使用不同的分析器和分词器)。不幸的是,分析后的数据通常不再适合显示。设置“stored=true”保证可以以原始形式检索原始数据。

关于java - Lucene中Field和StringField有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40699497/

相关文章:

java - 遍历集合并继续

java - grails spock 测试失败,显示 'java.lang.IllegalArgumentException: ServletContext must not be null'

java - Spring Jdbc声明性事务已创建但未执行任何操作

elasticsearch - 如何在不影响性能,可扩展性的前提下获得更好的相关性,以及如何避免Elasticsearch的分片效应

java - 如何执行分面搜索?

Solr + DIH + Tika : indexing huge amount of files, 如何处理删除的文件?

java - 如何用 Java 读取 DICOM 文件的内容?

lucene - 每个领域的不同分析器

lucene - Sitecore 自定义索引配置语言

java - 如何将ipv6字符串地址转换为16字节?