Apache Solr父子文档索引:新手求助获取含子文档的搜索结果方法
嘿,我刚接触Solr的时候也在嵌套子文档这块摸不着头脑,别慌,咱们一步步把这个问题解决掉!
配置DataImportHandler来导入嵌套子文档
首先,你需要在现有的父实体里嵌套子实体,通过关联字段把父表和子表的数据绑定起来。假设你的子表(比如叫CHILD_TABLE)是通过PARENT_ID字段关联父表的IDENTIFIER,那可以把你的data-config.xml补全成这样:
<entity name="products" query="SELECT DISTINCT IDENTIFIER,PDT_NAME,PDT_DESCRIPTION FROM PARENT_TABLE" deltaQuery="SELECT IDENTIFIER FROM PARENT_TABLE WHERE LAST_MODIFIED_DATE > '${dataimporter.last_index_time}'"> <field column="IDENTIFIER" name="pdtid" /> <field column="PDT_NAME" name="productname" /> <field column="PDT_DESCRIPTION" name="productdescription" /> <!-- 嵌套子实体:关联父文档的IDENTIFIER --> <entity name="product_features" query="SELECT FEATURE_NAME, FEATURE_VALUE FROM CHILD_TABLE WHERE PARENT_ID = '${products.IDENTIFIER}'" deltaQuery="SELECT PARENT_ID FROM CHILD_TABLE WHERE LAST_MODIFIED_DATE > '${dataimporter.last_index_time}'" parentDeltaQuery="SELECT IDENTIFIER FROM PARENT_TABLE WHERE IDENTIFIER = '${product_features.PARENT_ID}'"> <field column="FEATURE_NAME" name="featname" /> <field column="FEATURE_VALUE" name="featvalue" /> </entity> </entity>
关键配置说明
- 子实体的
query里用${products.IDENTIFIER}直接引用父实体的IDENTIFIER字段,确保子表数据能精准关联到对应父文档 deltaQuery用于子表的增量更新:当子表数据修改时,触发子文档的重新导入parentDeltaQuery很重要:当子文档更新时,它会告诉Solr对应的父文档也需要重新索引,保证父子数据的一致性
配置Schema支持嵌套文档
接下来要确保你的Solr Schema(managed-schema或schema.xml)里有_root_字段,这是Solr处理嵌套文档的核心标识,用来区分根文档(父文档)和子文档:
<field name="_root_" type="string" indexed="true" stored="false"/>
另外,根据子文档字段的需求,定义对应的字段(比如子文档的特征名和特征值):
<field name="featname" type="string" indexed="true" stored="true" multiValued="true"/> <field name="featvalue" type="text_general" indexed="true" stored="true" multiValued="true"/>
这里设置multiValued="true"是因为一个父文档可能对应多个子文档,多个子字段会被存为数组形式。
搜索时获取包含子文档的结果
完成导入后,就可以用Solr的Block Join查询来获取包含子文档的完整结果了:
1. 查询父文档并返回关联子文档
用fl参数指定返回所有父字段,同时加上[child]参数拉取子文档:
q=pdtid:123 fl=*,[child parentFilter="pdtid:[* TO *]"]
这里parentFilter="pdtid:[* TO *]"用来标识所有父文档(因为父文档都有pdtid字段,子文档没有)。
2. 通过子文档内容搜索父文档
如果你想通过子文档的特征找到对应的父文档,可以用Block Join的父查询语法:
q={!parent which="pdtid:[* TO *]"}featvalue:"waterproof"
这个查询会返回所有包含featvalue为waterproof的子文档的父文档。
小提示
- 先做一次全量导入,然后在Solr Admin的Query页面测试,查看返回的JSON结构里是否包含子文档的字段(比如
featname和featvalue会以数组形式呈现) - 增量更新期间,确保父表和子表的
LAST_MODIFIED_DATE字段都正确维护,否则增量导入会失效
内容的提问来源于stack exchange,提问作者Rekha
相关产品推荐
相关产品推荐

