【发布时间】:2011-11-04 15:26:00
【问题描述】:
我想使用以下逻辑在 Lucene(实际上是 Lucene.NET,但我可以根据需要从 Java 转换)中设置搜索:
- 搜索字符串为:A B C
- 在索引中的一个字段中搜索与 A、B 或 C 匹配的任何内容。(查询:
(field1:A field1:B field1:C)) - 对于在第 2 步中不匹配的每个字词,在第二个字段中搜索它,同时保留第一次搜索的结果(查询:
(+(field1:A) +(field2:B field2:C))) - 对于在步骤 3 中不匹配的每个字词,搜索第三个字段...
- 继续直到字段用完,或者搜索已用完所有术语。
目前,我的代码可以测试给定的搜索是否产生 NO 结果,并将所有产生结果的搜索结果组合在一起。但是在它对每个字段进行测试之前我没有办法阻止它(这不必要地限制了结果) - 它目前以如下查询结束:(+(field1:A field1:B field1:C) +(field3:A field3:B field3:C)) 当我希望它是(+(field1:A field1:C) +(field3:B)) 时。我不能只查看第一次搜索的结果并从搜索字符串中删除单词,因为分析器在解析搜索时会破坏单词,我无法解开它们以找出原始的它对应的搜索词。
有什么建议吗?
编辑: 好的,通常我更喜欢抽象地描述我的问题,但我认为其中的某些部分在这个过程中会丢失,所以我会更具体。
我正在为需要多层搜索逻辑的网站构建搜索引擎。我将追踪的一些示例搜索是:
- 耳机
- 怪兽耳机
- 白色怪兽耳机
- 白色 Foobar 耳机
索引包含具有七个字段的文档 - 与此示例相关的是:
- “datattype”:一个字符串,表示该文档所代表的项目类型(产品、类别、品牌),因此我们知道如何显示它
- “品牌”:相关的品牌(类别有多个品牌,产品和品牌各有一个)
- “路径”:给定类别的路径(即“音频 > 耳机 > 入耳式”的“音频耳机入耳式”)
- “关键词”:描述产品的各种不同之处。
总的来说,搜索的每一步的逻辑如下:
- 检查我们是否有匹配项。
- 如果是,请根据匹配项过滤结果,并在下一步中继续解析其余搜索词。
- 如果没有,请在下一步中解析搜索词。
每个步骤都类似于:
- 搜索类别
- 搜索品牌
- 搜索关键字
以下是这三个示例搜索的结果:
-
耳机
- 搜索类别:
+path:headphones +datatype:Category - 有匹配项(耳机类别),原始查询中没有留下任何单词,因此我们将其返回。
- 搜索类别:
-
怪物耳机
- 搜索类别:`+(path:monster path:headphones) +datatype:Category
- 找到了
path:headphones和datatype:Category的匹配项,导致“Monster”不匹配 - 搜索品牌:
+path:headphones +brand:monster - 找到了
path:headphones和brand:monster的匹配项,原始查询中没有留下任何单词,因此我们将 Monster 的所有耳机归还。
-
白色怪物耳机
- 搜索类别:
+(path:monster path:headphones path:white) +datatype:Category - 找到了
path:headphones和datatype:Category的匹配项,导致“White”和“Monster”不匹配 - 搜索品牌:
+path:headphones +(brand:monster +brand:white) - 找到了
path:headphones和brand:monster的匹配项,“白色”不匹配 - 搜索关键字:
+path:headphones +brand:monster +keywords:white - 有匹配项,原始查询中没有留下任何单词,因此我们返回它们。
- 搜索类别:
-
白色 Foobar 耳机
- 搜索类别:
+(path:foobar path:headphones path:white) +datatype:Category - 找到了
path:headphones和datatype:Category的匹配项,“White”和“Foobar”不匹配 - 搜索品牌:
+path:headphones +(brand:foobar +brand:white) - 没有找到,所以我们继续。
- 搜索关键字:
+path:headphones +(keywords:white keywords:foobar) - 找到了
path:headphones和keywords:white的匹配项,导致“Foobar”不匹配 - ...(继续搜索其他字段,包括产品描述)...
- 仍有未匹配的搜索词(“Foobar”),返回“未找到结果”
- 搜索类别:
我的问题是双重的:
- 我不希望在一切都匹配后继续匹配(只有产品有描述,所以一旦达到该步骤,我们将永远不会返回不是产品的东西)。我可以使用来自here 的denis 的GetHitTerms 来管理这个问题,但我最终会在所有后续字段中搜索第一个匹配的术语,直到所有内容都匹配(即在示例#2 中,我将拥有
+path:headphones +(brand:headphones brand:monster))。李> - 尽管上面有我的示例,但我在路径字段上的实际搜索查询看起来像
+path:headphon +datatype:Taxonomy,因为我正在修改它以进行搜索。所以我不能把匹配的词从原始查询中删除(因为“headphon”!=“headphones”)。
希望这能让我更清楚我在寻找什么。
【问题讨论】:
-
你看过这个吗? cwiki.apache.org/LUCENENET/simple-faceted-search.html可能有你可以使用的想法。
-
@denis:乍一看,这确实是我需要的。我需要更深入地研究它才能确定,但它看起来确实很有希望。
-
@denis:好消息和坏消息。它似乎确实是我需要的,但我的数据集太大了,无法处理。即使我提高了 MAX_FACETS 常量。我有 455 个品牌词、251 个路径词和 10094 个关键字词,仅来自上面的字段。如果它涵盖了除描述之外的所有方面,它的权重将接近 4 万亿个方面。
-
我敢打赌,您还没有阅读该页面中的
References to adding faceted to Lucene.Net section。还有其他利用 Collector 类进行分面搜索的技巧。见mail-archives.apache.org/mod_mbox/lucene-lucene-net-dev/… -
@denis:我现在已经阅读了,但我不明白如何处理结果,或者如何告诉它我希望多个字段成为我的搜索的一部分。
标签: java lucene lucene.net