【问题标题】:Solr - How do I get the number of documents for each field containing the search term within that field in Solr?Solr - 如何获取包含 Solr 中该字段中搜索词的每个字段的文档数?
【发布时间】:2012-12-19 09:01:16
【问题描述】:

想象一个像下面这样的索引:

id   partno      name          description
1    1000.001    Apple iPod    iPod by Apple
2    1000.123    Apple iPhone  The iPhone

当用户搜索“Apple”时,两个文档都会返回。现在,我想通过将搜索限制在一个或多个字段中包含包含“Apple”一词的文档的字段,让用户可以缩小结果范围。

因此,理想情况下,用户在第一次查询后会在 ui 的过滤器部分看到类似的内容:

按字段过滤
name (2)
description (1)

当用户对“description”字段应用过滤器时,只会返回“description”字段中包含“Apple”一词的文档。所以第二个请求的结果集将只是 iPod 文档。为此,我会使用?q=Apple&qf=description 之类的查询(我使用的是Extended DisMax Query Parser

我如何使用 Solr 实现这一点?

我已经尝试过分面、分组和突出显示组件,但并没有真正找到合适的解决方案。


[更新]
再次说明这一点:这里的主要问题是获取显示“按字段过滤”部分所需的信息。这包括字段的名称和每个字段的命中。发送应用了其中一个过滤器的第二个请求已经可以了。

【问题讨论】:

    标签: solr


    【解决方案1】:

    Solr 只是普通的不这样做。如果你绝对需要它,我会尝试使用多请求解决方案并对其进行基准测试——solr 往往比人们放在它前面的要快得多,所以几个请求可能没什么大不了的。

    【讨论】:

    • 不是我想听到的答案 ;-) 你似乎很确定这一点。你认为这可以很容易地作为 Solr 的扩展来实现吗?我认为在 Solr 方面收集这些信息不会太难。
    • 如果您打算编写自己的扩展/插件,那么是的,这是完全可行的!不像链接查询那么容易,虽然...
    • Solr 通过facet.query 确实做到了这一点,但您需要对每个字段重复查询。因此它与多请求解决方案非常相似,但是是单个请求。
    【解决方案2】:

    您可以通过两个不同的搜索请求/查询来实现这一点:

    name:apple -> 2 次点击

    描述:苹果 -> 1 次点击

    编辑:

    您还可以实现自己的SearchComponent,在后台执行多个查询并将其放入SearchHandler 处理链中,这样您只需要在前端执行一个查询。

    【讨论】:

    • 听起来很合理,但缺点是,您必须再发送两个请求才能获得每个查询的命中数。由于我仍然需要“标准查询”(q=Apple)的结果,因此每个搜索操作需要三个请求。请纠正我,如果我错了。可以将这三个查询合并为一个以获得所需的结果吗?
    • 我添加了替代答案
    【解决方案3】:

    如果您希望每次都在相同的字段中搜索该术语,您有 2 个选项不会违反“单一查询”要求:

    1) copyField:在索引时将所有应该匹配的字段分组。只需一个复制字段,您的问题就不存在,如果您需要多个,您就在同一个地方。

    2)您可以每次在末尾动态添加"fq" 参数来过滤查询

    http://<your_url_and_stuff>/?q=Apple&fq=name:Apple ...
    

    如果您始终在相同的两个字段上进行搜索(或者您可以在查询之前设置它们),则此方法有效,否则您将始终需要至少第二个查询

    因为我说“你有 2 个选项”,但你实际上有 3 个(我急忙回答),这里是第三个:

    3) 他们这样描述的dismax plugin

    The DisMaxQParserPlugin is designed to process simple user entered phrases 
    (without heavy syntax) and search for the individual words across several fields 
    using different weighting (boosts) based on the significance of each field.
    

    所以,如果你可以使用它,你可能想看看它并从 qf 参数开始(这就是选项号 2 想要的内容,但我将其更改为 fq...不要不要问我为什么……)

    【讨论】:

    • 感谢您的回答。据我了解,如果我想知道搜索词是否在它所组成的任何字段中,copyfield 方法会很有用。我仍然需要手动识别包含值的实际字段和每个字段的总点击数,不是吗?关于您的第二个选项,您的意思是&amp;fq=name:Apple OR description:Apple?我想我再次必须手动识别和计数。
    • 是的,这就是我的意思。但我实际上将这个答案与我不打算在那里说的其他东西合并。显然,您还有我忘记的第三种选择。让我更新答案
    • 我确实忘记提及我已经在使用 (E)DisMax。 qf 参数将是我将搜索限制在过滤请求中的一个字段(我的问题的第二部分)的选择。更新了问题。
    【解决方案4】:

    SolrFaceting 应该可以解决您的问题。 看看Examples

    【讨论】:

    • Solr faceting 不适用于正在搜索的字段。它将返回搜索结果的构面。
    【解决方案5】:

    这可以通过Solr faceting 来实现,但它并不整洁。例如,我可以发出以下查询:

    /select?q=*:*&rows=0&facet=true&facet.query=title:donkey&facet.query=text:donkey&wt=json
    

    titletext 字段中查找包含donkey 的文档数。我可能会收到这样的回复:

    {
     "responseHeader":{"status":0,"QTime":1,"params":{"facet":"true","facet.query":["title:donkey","text:donkey"],"q":"*:*","wt":"json","rows":"0"}},
     "response":{"numFound":3365840,"start":0,"docs":[]},
     "facet_counts":{
      "facet_queries":{
       "title:donkey":127,
       "text:donkey":4108
      },
      "facet_fields":{},
      "facet_dates":{},
      "facet_ranges":{}
     }
    }
    

    由于您还希望将文档返回用于字段分离查询,因此可以使用以下方法:

    /select?q=donkey&defType=edismax&qf=text+titlle&rows=10&facet=true&facet.query=title:donkey&facet.query=text:donkey&wt=json
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 2019-02-15
      • 1970-01-01
      • 2012-10-21
      • 2016-10-10
      • 2011-11-06
      • 1970-01-01
      相关资源
      最近更新 更多