如何在Solr Schema中正确定义嵌套复杂类型字段?
问题原因
你直接通过gameDetails.startTime这种点分隔的名称定义字段,Solr会自动将输入的嵌套JSON结构扁平化处理,把嵌套字段拆解为顶级字段,因此无法保留原有的数组嵌套格式。
正确实现方案
方案1:使用Solr嵌套文档(Nested Documents)
适合需要对嵌套对象独立索引、查询的场景,每个gameDetails对象作为主文档的子文档:
1. 定义字段
除基础字段外,直接定义子文档的独立字段(Solr默认支持嵌套文档,无需额外全局配置):
{ "add-field": [ { "name": "sessionId", "type": "plong", "stored": true, "indexed": true }, { "name": "sessionName", "type": "string", "stored": true, "indexed": true }, { "name": "startTime", "type": "pdate", "stored": true, "indexed": true }, { "name": "displayName", "type": "string", "stored": true, "indexed": true } ] }
2. 提交嵌套格式的文档
将gameDetails数组转换为_childDocuments_字段的子文档列表(子文档需指定唯一ID):
{ "sessionId":413431, "sessionName":"Test Session", "_childDocuments_": [ { "id": "child-game-1", "startTime":"2024-01-15T19:45:15Z", "displayName":"string" } ] }
3. 查询嵌套文档
使用{!child}语法关联主文档与子文档,或通过fl参数指定返回子文档字段:
http://localhost:8983/solr/testComplex/select?q=sessionId:413431&fl=*,[child parentFilter=sessionId:413431]
方案2:使用JSON字段类型存储完整嵌套结构
如果不需要对嵌套对象内部字段单独索引,仅需完整保留并返回原JSON结构,可使用Solr的json字段类型:
1. 定义JSON类型字段
{ "add-field": [ { "name": "sessionId", "type": "plong", "stored": true, "indexed": true }, { "name": "sessionName", "type": "string", "stored": true, "indexed": true }, { "name": "gameDetails", "type": "json", "stored": true, "indexed": false // 如需索引内部字段,可配置jsonFieldType映射类型 } ] }
2. 提交原格式文档
直接提交你最初的JSON数据即可,Solr会完整存储gameDetails的数组嵌套结构:
{ "sessionId":413431, "sessionName":"Test Session", "gameDetails":[ { "startTime":"2024-01-15T19:45:15Z", "displayName":"string" } ] }
方案3:使用结构化字段(Solr 8.0+)
Solr 8.0及以上版本支持直接定义结构化对象字段,完美匹配嵌套数组结构:
1. 定义结构化字段类型与字段
{ "add-field-type": { "name": "gameDetailsType", "class": "solr.StructField", "fields": [ {"name": "startTime", "type": "pdate", "stored": true, "indexed": true}, {"name": "displayName", "type": "string", "stored": true, "indexed": true} ] }, "add-field": [ { "name": "sessionId", "type": "plong", "stored": true, "indexed": true }, { "name": "sessionName", "type": "string", "stored": true, "indexed": true }, { "name": "gameDetails", "type": "gameDetailsType", "multiValued": true, // 因为是数组,必须开启多值 "stored": true, "indexed": true } ] }
2. 提交原格式文档
直接提交最初的JSON数据,Solr会保留gameDetails的数组嵌套结构,同时支持对内部字段的精准查询。
内容的提问来源于stack exchange,提问作者Tsvetoslav Tsvetkov
相关产品推荐
相关产品推荐

