我正在尝试使用data-config导入Solr 5.1.0和5.2.1,该数据配置应生成具有以下结构的文档:
<parentDoc>
<someParentStuff/>
<childDoc>
<someChildStuff/>
</childDoc>
</parentDoc>
根据我对this question about nested entities in DIH上的一个答案的理解,我的Solr版本应该能够使用以下data-config.xml
创建上述结构:
<dataConfig>
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver"
url=""
user=""
password=""
batchSize="-1"
/>
<document name="">
<entity rootEntity="true" name="parent" pk="parent_id" query="select * from parent">
<field column="parent_id" name="parent_id" />
<entity child="true" name="child" query="select * from child where parent_id='${parent.parent_id}'">
<field column="parent_id" name="parent_id" />
<field column="item_status" name="item_status" />
</entity>
</entity>
</document>
</dataConfig>
然而,当我执行full-import
时,我得到:
<result name="response" numFound="2" start="0">
<doc>
<long name="parent_id">477</long> <!-- This is from the child -->
<str name="item_status">WS</str>
</doc>
<doc>
<long name="parent_id">477</long> <!-- This is from the parent -->
</doc>
</result>
我理解的是你应该在5.1.0之前得到的非规范化布局;但是,我期待:
<result name="response" numFound="1" start="0">
<doc>
<long name="parent_id">477</long>
<doc>
<long name="parent_id">477</long>
<str name="item_status">WS</str>
</doc>
</doc>
</result>
我需要做些什么才能获得所需的文档结构?我是否误解了DIH中的嵌套实体应该做什么?
答案 0 :(得分:3)
除非有人向我倾诉告诉我,否则我似乎真的误解了Solr 5.1.0+中父子文档的创建。我期待能够嵌入文件并让它们归还,但Solr不可能做到这一点(至少在这一点上。未来是个谜。)
Solr是一个平面文档模型。这意味着它不能以我原始问题中想要的方式模拟父子关系。没有筑巢。一切都是扁平化和非规范化的。
Solr所做的是它在一个连续的块中在其父级旁边添加n个子文档。例如:
childDoc1 childDoc2 childDoc3 parent
这种结构实际上反映在我曾经错误的文件中#34;从索尔回来:
<result name="response" numFound="2" start="0">
<doc>
<long name="parent_id">477</long> <!-- This is from the child -->
<str name="item_status">WS</str>
</doc>
<doc>
<long name="parent_id">477</long> <!-- This is from the parent -->
</doc>
</result>
在Solr 5.0之后的dih中提供的嵌套文档支持实际上是人们过去必须索引嵌套文档的旧方式的附加或彻底替换,并且似乎也在处理更新子文档和父文档。同一时间给你。很方便!
那么,当Solr破坏你计划好的嵌套文档模型时,你如何表达亲子关系?您必须获取父文档和子文档,并在应用程序中管理关系。你如何得到父母和孩子?
答案是阻止连接。
在查询时使用块连接,然后在应用程序中将这些文档处理为所需的结构。让我们看看两个块连接查询,因为它们起初看起来有点奇怪。
{!parent which='type:parent'}item_id:5918307
此块连接查询说,&#34;获取包含一个或多个子文档的父文档,其中item_id
为5918307.&#34;
{!child of='type:parent'}
(fieldA:TERM^100.0 OR fieldB:term^100.0 OR fieldC:term OR (fieldD:term^20.0)) AND (instock:true^9999.0)
这个块连接查询说,&#34;给我一个或多个子文档,其父文档包含单词&quot; term&#39;并且有货。&#34;
执行!child
查询时,请勿搜索子字段。因此,引用第一个示例,您不会搜索item_id
,因为这会给您500错误。
您会注意到这些查询中的type
字段。您必须自己将其添加到架构和数据配置中。在架构中,它看起来像这样:
<!-- use this field to differentiate between parent and child docs -->
<field name="type" type="string" indexed="true" stored="false" />
然后在data-config.xml
中,为父母执行以下操作:
if ('true' = 'true', 'parent', 'parent') as type
对孩子也这样做,除了替换孩子&#34;在哪里放置&#34; parent&#34;之前。
所以最后你可能最终会进行两次查询,但是看起来添加块连接解析器似乎不会增加查询时间。我看到每个查询可能额外增加50或100毫秒。
您通常也可以通过智能连接来绕过需要嵌套的文档。然而,我发现,因为儿童文件现在与父文件混合在一起,你有一个&#34;复制&#34;每个父母在索引中具有特定子信息的情况。在这种情况下,您将从第一个文档中获取已知的父字段及其子字段。对于其他文档,您只需抓住子字段。
另一种选择,当您只想要父文档并且不想要返回大量其他文档时,就是使用分组查询;但是,我不推荐它。当我在一个返回大量结果的查询上尝试时,我看到查询时间从10ms到250ms一直到500ms-1s范围。