查询两个字段相等的文档?

Hen*_*nry 4 lucene solr

solr中有两个文本字段,它们都是白色空格标记化并具有小写过滤器.下面是架构:

<fieldType name="text_ac" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

<field name="field1" type="text_ac" indexed="true" stored="true" required="false" omitNorms="true" default=""/>

<field name="field2" type="text_ac" indexed="true" stored="true" required="false" omitNorms="true" default=""/>
Run Code Online (Sandbox Code Playgroud)

如何在查询时(field1 == field2)查询solr返回整个字符串field1与field2相同的结果?

谢谢.

fem*_*gon 10

据我所知,在Solr或Lucene核心中不支持将文档中的一个字段与另一个字段进行比较.

完成此操作的一种简单方法是在索引时执行比较,并将结果存储在索引中.也就是说,如果你有field1field2,创建一个字段1_equals_2,并将其编入索引true,如果它们在添加文档时基于你的比较是相等的.然后你可以简单地搜索1_equals_2:true.


Nic*_*zza 7

方法 1 - frange 解析器

正如@dduo 所提到的,您可以使用https://lucene.apache.org/solr/guide/6_6/other-parsers.html#OtherParsers-FunctionRangeQueryParser。这是 Trey Grainger(Solr in Action 的作者之一)所说的这样做的方式:

q=*:*&fq={!frange l=1 u=1 v=$equals}&equals=if(eq(field1,field2),1,0)
Run Code Online (Sandbox Code Playgroud)

我对此进行了测试,它适用于在大约 10 秒的查询中包含 1.4 亿个文档的集合,结果集中有 600,000 个文档。

所以这有效,但有点慢。

方法 2 - 使用流表达式

以下表达式似乎可以完成我们在这里要做的事情:

having(search(your_collection_name, q="*:*", sort="id asc"), eq(field1, field2))
Run Code Online (Sandbox Code Playgroud)

这似乎性能更高,因为它返回即时结果。因此,如果您可以使用流式表达式,这可能是获得所需内容的更快方法。