SOLR模式处理多个连接的多值字段

时间:2014-03-07 08:29:50

标签: solr

假设你有这样的文件:

doc1:
 id:1
 text: ...
 references: Journal1, 2013, pag 123
 references: Journal2, 2014, pag 345

doc2
 id:2
 text:...
 references: Journal2, 2013, pag 678
 references: Journal1, 2014, pag 901

如何构建我的架构以通过引用搜索文档? 我的第一个假设是这样的:

<doc>
 <field name="id">1</field>
 <field name="text">...</field>
 <field name="ref_journal">Journal1</field>
 <field name="ref_journal">Journal2</field>
 <field name="ref_year">2013</field>
 <field name="ref_year">2014</field>
 <field name="ref_page">123</field>
 <field name="ref_page">456</field>
</doc>
<doc>
 <field name="id">2</field>
 <field name="text">...</field>
 <field name="ref_journal">Journal2</field>
 <field name="ref_journal">Journal1</field>
 <field name="ref_year">2013</field>
 <field name="ref_year">2014</field>
 <field name="ref_page">678</field>
 <field name="ref_page">901</field>
</doc>

但是通过这种方式,我无法强制首个ref_journal字段与第一个ref_year字段相关联,因此搜索ref_journal:Journal1 AND ref_year:2013将错误地匹配这两个文档。 有没有办法拥有多个“连接”的多值字段?

3 个答案:

答案 0 :(得分:3)

如果您只需要搜索确切的值,那么一个棘手的解决方案就是在一个多值字段中使用适当的标记化程序连接多个属性。

定义&#34; ref&#34;像这样打字:

<fieldType name="ref" class="solr.TextField" positionIncrementGap="100">
  <analyzer>
    <tokenizer class="solr.PatternTokenizerFactory" pattern="\s*;\s*"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

创建一个多值字段来存储引用:

<field name="ref" type="ref" indexed="true" stored="true" multiValued="true" />

格式化数据如下:

<doc>
 <field name="id">1</field>
 <field name="text">...</field>
 <field name="ref">journal:Journal1; year:2013 ; page:123</field>
 <field name="ref">journal:Journal2; year:2014 ; page:456</field>
</doc>
<doc>
 <field name="id">2</field>
 <field name="text">...</field>
 <field name="ref">journal:Journal2; year:2013; page:678;</field>
 <field name="ref">journal:Journal1; year:2014; page:901;</field>
</doc>

使用邻近匹配进行搜索:

ref:"year:2014; journal:Journal2"~100

请注意:

  • 您无法在数据中使用分号:如果您需要,您可以找到另一个合适的分隔符。

  • positionIncrementGap必须大于参考中可能属性的数量,以避免不同字段的匹​​配。

  • 您无法使用范围查询

这不是一般解决方案,但在大多数情况下,它可能足够且可能更容易实施。

答案 1 :(得分:2)

看看BlockJoin,它提供了一些支持。请注意,它与sql db不完全可比,但有一些限制,但它确实支持一些用例。如果你真的需要这个功能,请查看它,即使它使其他事情变得更难,也可以节省你的时间。

答案 2 :(得分:1)

几天前我也遇到了类似的问题。所以,我可以建议你一个不同的解决方案。

让我们借助您提供的数据。我会将2个文档存储为4个不同的Solr文档。如果您简化文档结构,而不是执行繁重的连接查询,那么Solr总是更好。

<doc>
 <field name="id">1</field>
 <field name="text">...</field>
 <field name="somefield">doc1</field>
 <field name="ref_journal">Journal1</field>
 <field name="ref_year">2013</field>
 <field name="ref_page">123</field>
</doc>
<doc>
 <field name="id">2</field>
 <field name="text">...</field>
 <field name="somefield">doc1</field>
 <field name="ref_journal">Journal2</field>
 <field name="ref_year">2014</field>
 <field name="ref_page">456</field>
</doc>
<doc>
 <field name="id">3</field>
 <field name="text">...</field>
 <field name="somefield">doc2</field>
 <field name="ref_journal">Journal2</field>
 <field name="ref_year">2013</field>
 <field name="ref_page">678</field>
</doc><doc>
 <field name="id">4</field>
 <field name="text">...</field>
 <field name="somefield">doc2</field>
 <field name="ref_journal">Journal1</field>
 <field name="ref_year">2014</field>
 <field name="ref_page">901</field>
</doc>

现在,如果您查询ref_journal:Journal1 AND ref_year:2013仅匹配单个Solr文档。我还添加了一个名为“ somefield ”的字段,该字段表示前2个Solr文档属于单个文档,另外2个文档属于不同的文档。这样您就可以保留与文档相关的所有信息。并且还正确建立了文件之间的联系。

还有一件事。请不要担心数据冗余和查询性能。因为简单的查询总是会给您提供比连接查询更好的性能。索尔在加入时并不是那么好。

希望这会有所帮助。