如何在Solr中正确索引包含_childDocuments_的JSON对象?
嘿,我来帮你搞定Solr嵌套文档的问题!你遇到的情况其实很常见——默认情况下Solr会把父子文档作为独立条目返回,要让它们嵌套显示,得从Schema配置、索引方式和查询语法这几个地方入手,一步步来:
1. 确认_root_字段的正确配置
你提到已经添加了_root_字段,但得确保它的类型和属性完全符合要求。这个字段是Solr关联父子文档的核心,必须是string类型,且设置为indexed="true"(不需要stored,除非你要直接查看它的值)。
如果用的是传统的schema.xml,添加以下字段配置:
<field name="_root_" type="string" indexed="true" stored="false" />
如果用的是Solr默认的Managed Schema,可以通过API添加:
curl -X POST -H 'Content-type:application/json' --data-binary '{ "add-field":{ "name":"_root_", "type":"string", "indexed":true, "stored":false } }' http://localhost:8983/solr/your_core/schema
替换your_core为你的Core名称,之后记得Reload你的Core(可以在Solr Admin的「Core Actions」里点击Reload,或者用API:curl http://localhost:8983/solr/admin/cores?action=RELOAD&core=your_core)。
2. 确保索引提交的正确方式
你的JSON结构是对的,但要通过Solr的Update API提交,并且执行commit操作让索引变更生效:
提交嵌套文档:
curl -X POST -H 'Content-Type: application/json' http://localhost:8983/solr/your_core/update --data-binary ' [ { "id" : "1", "language":"nl", "name" : "Caroline", "_childDocuments_" : [ { "id": "doc_1", "type_s": "document", "text": "this is the text" } ] } ]'
然后手动执行commit:
curl http://localhost:8983/solr/your_core/update?commit=true
这一步很关键,Solr默认的软提交可能不会立即把父子关联关系写入磁盘,手动commit能确保关联逻辑被正确建立。
3. 使用嵌套查询语法获取嵌套结果
你之前用q=*:*得到扁平化结果,是因为Solr默认会返回所有匹配的文档,不管父子关系。要让子文档嵌套显示,需要用Solr的**[child]查询语法**指定返回父文档的同时包含子文档:
比如查询父文档id:1并嵌套返回它的子文档:
curl "http://localhost:8983/solr/your_core/select?q=id:1&fl=*,[child parentFilter=id:1]"
这个查询的fl参数中,*表示返回父文档的所有字段,[child parentFilter=id:1]表示把父文档id:1对应的子文档嵌套进来。
如果要获取所有父文档及其子文档,可以这样查询:
curl "http://localhost:8983/solr/your_core/select?q=_root_:*&fl=*,[child parentFilter=_root_:*]"
(_root_:*匹配所有父文档,因为父文档的_root_值等于自己的id,子文档的_root_值等于父文档的id)
验证父子关系是否正确建立
你可以先查询子文档的_root_字段,确认它关联到了父文档:
curl "http://localhost:8983/solr/your_core/select?q=id:doc_1&fl=id,_root_"
返回结果里的_root_应该是"1",这说明父子关联已经正确建立了。
内容的提问来源于stack exchange,提问作者blah

