ElasticSearch 查询嵌套对象未按预期工作
ElasticSearch querying nested objects not working as expected
所以我试图在 ElasticSearch 中搜索嵌套对象,但我没有正确执行某些操作,因为我没有得到任何结果。
我运行以下命令:-
创建索引和映射
PUT /demo
{
"mappings": {
"person": {
"properties": {
"children": {
"type": "nested",
"properties": {
"fullName": {
"type": "string"
},
"gender": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
添加个人文档
POST /demo/person/1
{
"children": [{
"fullName" : "Bob Smith",
"gender": "M"
}]
}
这些都按预期执行。但是,当我按照 documentation 中的概述搜索它们时,我没有得到任何结果。
查询
POST /demo/person/_search
{
"query": {
"bool": {
"must": [{
"match_all": {}
},
{
"nested": {
"path": "children",
"query": {
"bool": {
"must": [{
"match": {
"fullName": "Bob Smith"
}
}]
}
}
}
}]
}
}
}
我做错了什么?
只是为了记录答案,问题是 all 查询和过滤器需要完整的字段名称。在上面的例子中,文档被索引为:
{
"children": [
{
"fullName" : "Bob Smith",
"gender": "M"
}
]
}
要查询gender
,必须按children.gender
访问,要查询fullName
,必须按children.fullName
.
访问
所有 JSON 数据结构都被 Lucene 有效地扁平化了,这实际上是 nested
类型甚至存在的全部原因,所以:
{
"children": [
{
"fullName" : "Bob Smith",
"gender": "M"
},
{
"fullName" : "Jane Smith",
"gender": "F"
}
]
}
使用 object
类型(默认)变成这样:
"children.fullName": [ "Bob Smith", "Jane Smith" ]
"children.gender": [ "M", "F" ]
用 nested
类型变成:
{
"children.fullName": [ "Bob Smith" ]
"children.gender": [ "M" ]
}
{
"children.fullName": [ "Jane Smith" ]
"children.gender": [ "F" ]
}
其中 {}
用作嵌套文档边界(它们实际上不存在,但逻辑上存在)。
因此,无论您是否使用嵌套文档,您都需要提供字段名称的完整路径,即使最后一部分(例如,gender
)对于索引是唯一的。
相关兴趣:当数组中只有一个对象时,永远不要使用 nested
类型。它仅在您实际将其用作数组时才有用。如果它不是一个数组,那么平面版本以更少的开销提供完全相同的功能。如果有的文档有一个,有的文档不止一个,那么用nested
.
也是有意义的
所以我试图在 ElasticSearch 中搜索嵌套对象,但我没有正确执行某些操作,因为我没有得到任何结果。
我运行以下命令:-
创建索引和映射
PUT /demo
{
"mappings": {
"person": {
"properties": {
"children": {
"type": "nested",
"properties": {
"fullName": {
"type": "string"
},
"gender": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
添加个人文档
POST /demo/person/1
{
"children": [{
"fullName" : "Bob Smith",
"gender": "M"
}]
}
这些都按预期执行。但是,当我按照 documentation 中的概述搜索它们时,我没有得到任何结果。
查询
POST /demo/person/_search
{
"query": {
"bool": {
"must": [{
"match_all": {}
},
{
"nested": {
"path": "children",
"query": {
"bool": {
"must": [{
"match": {
"fullName": "Bob Smith"
}
}]
}
}
}
}]
}
}
}
我做错了什么?
只是为了记录答案,问题是 all 查询和过滤器需要完整的字段名称。在上面的例子中,文档被索引为:
{
"children": [
{
"fullName" : "Bob Smith",
"gender": "M"
}
]
}
要查询gender
,必须按children.gender
访问,要查询fullName
,必须按children.fullName
.
所有 JSON 数据结构都被 Lucene 有效地扁平化了,这实际上是 nested
类型甚至存在的全部原因,所以:
{
"children": [
{
"fullName" : "Bob Smith",
"gender": "M"
},
{
"fullName" : "Jane Smith",
"gender": "F"
}
]
}
使用 object
类型(默认)变成这样:
"children.fullName": [ "Bob Smith", "Jane Smith" ]
"children.gender": [ "M", "F" ]
用 nested
类型变成:
{
"children.fullName": [ "Bob Smith" ]
"children.gender": [ "M" ]
}
{
"children.fullName": [ "Jane Smith" ]
"children.gender": [ "F" ]
}
其中 {}
用作嵌套文档边界(它们实际上不存在,但逻辑上存在)。
因此,无论您是否使用嵌套文档,您都需要提供字段名称的完整路径,即使最后一部分(例如,gender
)对于索引是唯一的。
相关兴趣:当数组中只有一个对象时,永远不要使用 nested
类型。它仅在您实际将其用作数组时才有用。如果它不是一个数组,那么平面版本以更少的开销提供完全相同的功能。如果有的文档有一个,有的文档不止一个,那么用nested
.