Lucene查询排列

时间:2010-02-09 03:05:24

标签: lucene

我有一个关于执行涉及排列的lucene查询的问题。

假设我有两个字段:“name”和“keyword”,用户搜索“joes pizza restaurant”。我希望该搜索的某些部分与“名称”字段的完整内容匹配,而某些部分则匹配关键字字段的完整内容。它应该匹配所有提供的术语,并且应该匹配字段的全部内容。例如,它可以匹配:

1)名称:“joes restaurant”关键字:“披萨”
2)名称:“joes pizza”关键字:“restaurant”
3)名称:“披萨店”关键词:“乔斯”
4)名称:“披萨”关键词:“joes restaurant”
5)名称:“披萨乔”关键词:“餐馆”

但不匹配

6)名称:“大乔餐厅”关键字:“披萨” - 因为它不是全场的匹配
7)名称:“joes pizza restaurant”关键字:“nomatch” - 因为至少有一个术语应该与关键字字段匹配

我已经考虑过通过计算字段的所有排列和使用布尔查询来实现这一点的可能方法,但是随着术语数量的增加,这种方法不能很好地扩展。任何人都有任何线索如何有效地实现这种查询?

2 个答案:

答案 0 :(得分:1)

Lucene docs建议使用单独的字段,该字段是跨越多个字段的查询的“名称”和“关键字”字段的串联。在这个领域进行搜索。

答案 1 :(得分:0)

让我们将您的查询分为三个部分:

  1. “名称”字段和“关键字”字段都应包含查询的一部分。
  2. 两场比赛都应该是全场比赛。
  3. 匹配的联合应完全覆盖查询。
  4. 我会这样实现:

    1. 创建一个由原始查询中的标记组成的布尔查询。将它作为“必须”术语的分离。例如在示例中类似于:

      (姓名:joes OR name:restaurant OR name:pizza)AND(关键字:joes OR keyword:restaurant OR keyword:pizza) 与此查询匹配的任何文档都包含每个字段中原始查询的一部分。 (这可以是ConstantScoreQuery以节省时间)。

    2. 从第一个查询中获取匹配集。将字段内容提取为标记,并将它们存储在字符串集中。仅保留集合的并集等于原始查询中设置的字符串的匹配项,并且集合具有空的交集。 (这处理覆盖物 - 上面的第3项)。对于您的第一个示例,我们将设置{{joes“,”restaurant“}和{”pizza“}以满足这两个条件。

    3. 从左侧匹配中获取设定的大小,并将它们与字段长度进行比较。对于您的第一个示例,我们将设置2和1的大小,分别对应于字段长度2和1。

    4. 请注意,我的第2项和第3项不是常规Lucene评分的一部分,而是外部Java代码。