2010-02-09 76 views
1

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

说我有两个字段:“名称”和“关键词”和“招财披萨餐厅”用户搜索。我希望该搜索的某个部分与“名称”字段的全部内容匹配,并且要匹配关键字字段的全部内容。它应该匹配所有提供的条款,并且应该匹配字段的全部内容。例如,它可以匹配:

1)名称: “乔的餐厅” 的文章: “比萨”
2)名称: “乔的比萨” 的文章: “餐厅”
3)名称: “比萨餐厅” 的文章: “乔斯”
4)名称: “比萨” 的文章: “乔的餐厅”
5)名称: “比萨乔斯” 的文章: “餐厅”

,但它不会匹配

6)名称: “大乔餐厅”关键字:“比萨饼” - 因为它不是全场比赛
7)name:“joes pizza restaurant”关键字:“不匹配” - 因为至少有一个条款应该与关键字字段相匹配

我想过通过计算所有的排列字段和使用布尔查询,但是随着术语数量的增加,这不会很好地扩展。任何人都有任何线索如何有效地实现这种查询?

回答

1

Lucene文档推荐使用单独的字段,它是用于跨多个字段的查询的'name'和'keyword'字段的串联。做这个领域的搜索。

+0

结合去这听起来像合理的做法。 – Glen 2010-02-10 00:04:05

0

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

  1. 无论是“名称”字段和“关键字”字段中应包含查询的一部分。
  2. 两场比赛应该是全场比赛。
  3. 匹配的联合应该完全覆盖查询。

我会实现它是这样的:

  1. 创建原始查询的标记组成的布尔查询。将它作为“必须”术语的分解。例如在这个例子中是这样的:

    (name:joes OR name:restaurant OR name:pizza)AND(关键字:joes OR关键字:restaurant OR关键字:pizza) 与该查询匹配的任何文件具有原始查询的一部分在每个领域。 (这可能是一个ConstantScoreQuery来节省时间)。

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

  3. 选择左比赛的集大小,并将它们与字段长度。对于您的第一个示例,我们将设置大小为2和1,这应分别对应于2和1的字段长度。

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