31

我有一个~1 百万的产品文档 Solr 索引。我还有一大堆 UI 过滤器,例如类别、选项卡、价格范围、尺寸、颜色和其他一些过滤器。

让 q 选择所有内容(q=\*:\*)而 fq 中的所有其他过滤器是正确的方法吗?例子:

fq=(catid:90 OR catid:81) AND priceEng:[38 TO 40] AND (size:39 OR size:40 OR size:41 OR size:50 OR size:72) AND (colorGroup:Yellow OR colorGroup:Violet OR colorGroup:Orange ... AND (companyId:81 OR companyId:691 OR companyId:671 OR companyId:628 OR companyId:185 OR companyId:602 OR ... AND endShipDays:[* TO 7])

对我来说,从类别到公司 ID,从颜色和尺寸等一切都只是过滤器。这种方法在未来增长中的性能有什么问题吗?我应该将一些查询放在 q 中,哪些?

谢谢,

4

4 回答 4

52

最好尽可能使用过滤查询而不是普通查询。

FilterQuery能够利用FilterCache,与您的查询相比,这将是一个巨大的性能提升。

于 2012-07-24T09:09:03.780 回答
10

为了决定,我会查看有关字段的以下几点:

  1. 您的领域是否有固定的提升分数,或者您是否需要为该领域评分?如果是,就放到query中,因为上面说过,filter query不使用scores。
  2. 该字段的条件是否经常使用?如果是 - 再次,如前所述,过滤缓存可能会带来巨大的优势,但如果不是 - 它可能会更慢。
  3. 你的指数是恒定的吗?这有点类似于#2。如果您的索引经常更新,过滤查询的使用可能会成为瓶颈,而不是提高性能。

关于#3 的一些注意事项:根据我的经验,我有一个大索引,每隔几秒就会填充一次新文档,并且 autoSoftCommit 也设置为几秒。在软提交期间,打开了新的搜索器,这使缓存无效。所以真正发生了什么,过滤命中率几乎总是 0。我可以告诉更多:我发现第一次过滤查询运行比运行所有过滤条件移动到“q”而不是“ fq”。例如,当我使用“AND”将所有“fq”条件移动到主查询中时,我的查询用了 1 秒和 5 个过滤器查询(没有缓存命中)和 147 毫秒。但是,当然,当我停止索引更新时,相同的过滤器查询需要 0 毫秒,因为使用了缓存。所以这是需要考虑的事情。

您的问题还有其他几点:

  • 尽量不要在查询中使用通配符。它显着影响性能。因此,我建议使用一种条件,而不是“ : ”
  • 范围搜索也最好避免(如果可能)。使用通配符进行范围搜索甚至更多。这是关于您的“endShipDays:[* TO 7]”。例如,使用“endShipDays:(1 2 3 4 5 6 7)”会更有效,但这只是一个例子,有很多方法。

希望能帮助到你。

于 2016-02-12T19:57:16.737 回答
5

我使用qfq的方式。我在q上应用全文搜索,在fq上应用所有过滤器。假设您有字段关键字,您将使用 copyField 在架构中定义的字段进行全文搜索

<copyField source="id" dest="keyword"/>
<copyField source="category" dest="keyword"/>
<copyField source="product_name" dest="keyword"/>
<copyField source="color" dest="keyword"/>
<copyField source="location" dest="keyword"/>
<copyField source="price" dest="keyword"/>
<copyField source="title" dest="keyword"/>
<copyField source="description" dest="keyword"/>

我的查询看起来像

/select?q={keyword}&fq=category:fashion&fq=location:nyc

/select?q=jeans&fq=category:fashion&fq=location:nyc

正如 digitaljoel 建议的那样,如果您必须查询多个字段,那么最好使用多个 fq(请参阅上面的查询)而不是使用 AND 和 OR 与q

注意:在我的例子中,q default 指的是solrconfig.xml 中定义的field关键字

<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
     will be overridden by parameters in the request
  -->
 <lst name="defaults">
   <str name="echoParams">explicit</str>
   <int name="rows">10</int>
   <str name="df">keyword</str>
 </lst>
于 2015-03-23T07:32:52.453 回答
2

考虑您的查询,并将所有不需要评分且可重复的内容放入fq参数中。这样,在打开搜索器之间将命中 Solr 节点的连续查询将能够重用存储在 FilterCache 中的信息。

过滤器缓存将唯一过滤器存储为过滤器中的键 - 值是一个位数组,其中数组的每个条目表示给定文档是否与给定过滤器匹配。这样就很容易为下一个查询重新应用过滤器。但是,您当然会错过得分能力。

在查看您的查询时,我会通过使用多个fq值来简化它,其中包括:

fq=(catid:90 OR catid:81)
fq=priceEng:[38 TO 40]
fq=(size:39 OR size:40 OR size:41 OR size:50 OR size:72)
fq=(colorGroup:Yellow OR colorGroup:Violet OR colorGroup:Orange  ... ) 
fq=(companyId:81 OR companyId:691 OR companyId:671 OR companyId:628 OR companyId:185 OR companyId:602 OR ... ) 
fq=endShipDays:[* TO 7])

过滤器是附加的,所以查询会返回相同的结果,但至少对我来说更容易管理:)

于 2020-03-25T17:26:43.580 回答