1

在 Solr 4.10 中,我在 11 个分片核心中有 170.000.000 个文档。自 2008 年以来,每个文档都代表我网站中的一次访问,11 个核心中的每一个代表一年。

我需要找到一个项目列表的访问权限,所以像下面这样进行查询:

using facet.field, "QTime": 10557

(通过核心重新加载清理缓存后)

q=(owningItem:178350+OR+owningItem:51760+OR+owningItem:71585)+AND+statistics_type:view&shards=localhost:8080/solr//statistics-2014,localhost:8080/solr//statistics-2017,localhost: 8080/solr//statistics-2016,localhost:8080/solr//statistics-2008,localhost:8080/solr//statistics-2011,localhost:8080/solr//statistics-2012,localhost:8080/solr//statistics -2010,localhost:8080/solr//statistics-2013,localhost:8080/solr//statistics-2009,localhost:8080/solr//statistics-2015,localhost:8080/solr//statistics&facet.limit=4&facet.field =owningItem&facet.mincount=1

结果:

 "facet_counts": {
    "facet_queries": {},
    "facet_fields": {
      "owningItem": [
        "51760",
        3502,
        "71585",
        1860
      ]
    },
    "facet_dates": {},
    "facet_ranges": {},
    "facet_intervals": {}
  },

当我调试这个查询时,我可以看到,对于每个核心,返回的 facet.field 值不属于查询结果:

response={numFound=953,start=0,maxScore=1.9732983,docs=[]},sort_values={},facet_counts={facet_queries={},facet_fields={owningItem={51760=556,71585=397,**1=0,10=0,100=0,1000=0,10000=0,100000=0,100001=0,100002=0,100003=0,100004=0,100005=0,100007=0,100008=0,10001=0**}},facet_dates={},facet_ranges={},facet_intervals={}}

所以,我尝试使用 facet.query 而不是 facet.field

using facet.query, "QTime": 1346

q=(owningItem:178350+OR+owningItem:51760+OR+owningItem:71585)+AND+statistics_type:view&shards=localhost:8080/solr//statistics-2014,localhost:8080/solr//statistics-2017,localhost:8080/solr//statistics-2016,localhost:8080/solr//statistics-2008,localhost:8080/solr//statistics-2011,localhost:8080/solr//statistics-2012,localhost:8080/solr//statistics-2010,localhost:8080/solr//statistics-2013,localhost:8080/solr//statistics-2009,localhost:8080/solr//statistics-2015,localhost:8080/solr//statistics&facet.limit=4&facet.query=owningItem:178350&facet.query=owningItem:51760&facet.query=owningItem:71585&facet.mincount=1

 "facet_counts": {
    "facet_queries": {
      "owningItem:178350": 0,
      "owningItem:51760": 3502,
      "owningItem:71585": 1860
    },
    "facet_fields": {},
    "facet_dates": {},
    "facet_ranges": {},
    "facet_intervals": {}
  },

并调试,仅使用属于结果的项目:

response={numFound=953,start=0,maxScore=1.9732983,docs=[]},sort_values={},facet_counts={facet_queries={owningItem:178350=0,owningItem:51760=556,owningItem:71585=397},facet_fields={},facet_dates={},facet_ranges={},facet_intervals={}}

我得出的结论是 facet.field 的计算超过了 Solr 查询的结果。不过我觉得这个结论是不写的。

我的问题:

  • 为什么 facet.query 比 facet.field 快?

  • Solr 真的是对不属于查询结果的文档计算 facet.field 吗?

4

1 回答 1

0

由于您在分片环境中运行,因此每个分片必须返回比当前facet.limit要求它做的更多的项目。原因是这些方面可能在其他分片之一中具有更高的分数。它们不是在不属于查询集的文档上计算的(那么它们就不会是 0)。分面也在后台使用索引术语列表,因为即使计数为 0,也可以使用分面查询返回术语。

即分片 1 和 2 都是foo第二受欢迎的分片,每个分片有 30 次点击,而分片 1baz最受欢迎,但没有 31 的文档bar,分片 2bar最受欢迎,有 31,但没有文档baz。如果facet.limit设置为 1 并且仅返回该数量的方面,则foo永远不会返回(因为它是总体上最受欢迎的,但不是在任何分片中)。

这也告诉您为什么每个服务器都包含mincount低于请求的值的值。在我们之前的示例中,如果mincount设置为 31,并且该参数被传播到每个分片,foo则永远不会从分片返回。这就是为什么在返回最终的构面列表之后评估 mincount 的原因。在您的情况下,这些方面只是那些首先以 0 次命中排序的方面,但这是一种特殊情况(因为 0 对最终结果没有任何贡献,但从列表开头返回这些方面也没有任何作用,因为已检索术语并计算了它们的分数)。

您可以通过调整(10) 和(1.5)来控制Solr 如何对构面执行过度请求。facet.overrequest.countfacet.overrequest.ratio

在这些情况下,默认情况下会要求每个分片提供顶部的“facet.overrequest.count + (facet.overrequest.ratio * facet.limit)”约束。

当您使用方面查询时,这两者都不必发生。每个查询都在每个服务器上运行,并且这些查询的计数在返回给用户之前被合并。不用担心 facet.query 可能会返回其他节点上未返回的命中等。在我们的示例中,查询将返回 30 + 30、31 + 0 和 31 + 0。但您只能获得有关的统计信息您已经知道的术语,而不是那些可能相关的术语 - 但您没有查询。这就是区别。

于 2018-07-09T17:39:22.453 回答