2010-03-09 130 views
6

每个Lucene doc都是一个配方,每个配方都有配料。具有多个相同属性字段的Lucene索引

我的工作方向是能够搜索配料,并给出结果,说两种配料满足四种配比。 (例如)

那么如何将配料添加到文档?在solr中,我可以创建多个字段并将它们全部保存起来,我可能会因为只保存一种成分而做错了。

这也适用于像'标签'这样的字段。

p.sim使用Zend框架,如果它很重要。

回答

12

Lucene文档支持添加多个相同名称的字段。即可以反复调用:

document.add(new Field("name"), value) 

所以是你做的事:

# (pseudo-code) 
document1.add(new Field("ingredient"), "vanilla") 
document1.add(new Field("ingredient"), "strawberry") 
index.add(document) 

# And then search for 
index.search("ingredient", "vanilla" && "strawberry") 

你会得到文档1。但是,如果你搜索:

index.search("ingredient", "vanilla" && "apple") 

您将无法取回文档1

如果您搜寻:

index.search("ingredient", "vanilla" || "apple") 

你也还是会回到文档1

如果你想看到哪些成分相匹配,你可以简单地将文档保存的领域存储字段,然后对每个匹配文档检索的字段列表,并将它们与用户查询。

另请注意,默认情况下,PositionIncrementGap用于添加到文档中的名称相同的字段为0。

这意味着,如果你说:

index.search("ingredient", "chocolate orange") 

你能避免:

document1.add(new Field("ingredient"), "chocolate") 
    document1.add(new Field("ingredient"), "orange") 

那么这将是,如果它被称为“巧克力橙”,这可能匹配在一个单一成分处理这为PositionIncrementGap> 1设置了一个值,这将产生:

0匹配为:

index.search("ingredient", "chocolate orange") 

和1匹配:

index.search("ingredient", "chocolate" && "orange") 
0

我在这里看到的两种可能的方法:

  1. 进行非标准化数据 - 创建一个单独的文档,以配方各成分,让所有的文件为配方共同的配方ID。然后,在搜索过程中,聚合配方ID的所有匹配项。有点丑陋。
  2. 将所有成分连接成一个共同的字段,并将其作为“文本”进行索引。然后使用带有'OR'的布尔查询搜索配料(这在Java Lucene术语中称为'Should',我不知道PHP的等价物)。

我建议你尝试第二种方法,看看它是否有帮助。

相关问题