[英]Elasticsearch multi level nested query
具有多级嵌套字段的映射,如下所示:
{
otherFields....,
nestedField: {
type: "nested",
include_in_parent: true,
multiple: true,
properties: {
province: {
type: "nested",
include_in_parent: true,
multiple: true
},
properties: {
comuni: {
type: "nested",
include_in_parent: true,
multiple: true,
properties: {
nome: {
type: "string"
},
parziale: {
type: "boolean"
}
}
},
nome: {
type: "string"
}
}
}
},
regione: {
type: "string"
}
}
文档提到可以在此字段上执行查询https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-nested-query.html 。
使用此查询:
{
"size": 1,
"version": true,
"query": {
"filtered": {
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"regex_term": {
"field_2": {
"term": ".*701.*",
"ignorecase": true
}
}
}
]
}
},
"functions": [
{
"script_score": {
"script": "_score * -doc['field_2'].value.length()"
}
}
]
}
},
"filter": {
"nested": {
"path": "nestedField",
"filter": {
"bool": {
"must": [
{
"term": {
"nestedField.regione": "Lazio"
}
},
{
"bool": {
"must": [
{
"or": {
"filters": [
{
"term": {
"nestedField.province.nome": "Pordenone"
}
},
{
"not": {
"filter": {
"exists": {
"field": "nestedField.province.nome"
}
}
}
}
]
}
},
{
"or": {
"filters": [
{
"term": {
"nestedField.province.comuni.nome": "Udine"
}
},
{
"not": {
"filter": {
"exists": {
"field": "nestedField.province.comuni.nome"
}
}
}
}
]
}
}
]
}
}
]
}
}
}
}
}
}
}
函数分数部分看起来不错,但在嵌套过滤器部分都存在一些问题。 数据如下所示:
{
"_source": {
"otheFields" ...,
"nestedField": [
{
"regione": "Lazio"
},
{
"province": [
{
"nome": "Venezia"
},
{
"nome": "Treviso"
}
],
"regione": "Veneto"
},
{
"province": [
{
"comuni": [
{
"nome": "Varmo",
"parziale": false
}
],
"nome": "Udine"
}
],
"regione": "Friuli venezia giulia"
}
]
}
}
即使省字段丢失,查询也不会找到给定的记录,相反,如果我们对 regione 使用“Veneto”,对 provincia.nome 使用“Treviso”,并在另一个嵌套对象中使用 comune 字段,则它可以正常工作。
为什么这个查询不起作用?
尝试将您的条款更改为小写。 由于您没有在映射中指定分析器,因此使用标准分析器,它将术语转换为小写。
您的查询非常复杂,起初我以为您可能需要更多"nested"
子句,但是当我执行以下操作时,它似乎有效。 (我确实很快就完成了这个,所以如果我在这里展示的内容由于某种原因对你不起作用,请告诉我。)
我不得不"regex_term"
"query"
部分,因为我在"regex_term"
上遇到错误,但如果我"regex_term"
,如果我们只有一个文档,应该不会影响结果。
所以我创建了一个这样的索引(在"province"
的定义之后,你的一个大括号在错误的地方):
PUT /test_index
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"doc": {
"properties": {
"nestedField": {
"type": "nested",
"include_in_parent": true,
"multiple": true,
"properties": {
"province": {
"type": "nested",
"include_in_parent": true,
"multiple": true,
"properties": {
"comuni": {
"type": "nested",
"include_in_parent": true,
"multiple": true,
"properties": {
"nome": {
"type": "string"
},
"parziale": {
"type": "boolean"
}
}
},
"nome": {
"type": "string"
}
}
}
},
"regione": {
"type": "string"
}
}
}
}
}
}
添加了您的文档:
PUT /test_index/doc/1
{
"nestedField": [
{
"regione": "Lazio"
},
{
"province": [
{
"nome": "Venezia"
},
{
"nome": "Treviso"
}
],
"regione": "Veneto"
},
{
"province": [
{
"comuni": [
{
"nome": "Varmo",
"parziale": false
}
],
"nome": "Udine"
}
],
"regione": "Friuli venezia giulia"
}
]
}
然后运行这个修改后的查询:
POST /test_index/_search
{
"size": 1,
"version": true,
"query": {
"filtered": {
"filter": {
"nested": {
"path": "nestedField",
"filter": {
"bool": {
"must": [
{
"term": {
"nestedField.regione": "lazio"
}
},
{
"bool": {
"must": [
{
"or": {
"filters": [
{
"term": {
"nestedField.province.nome": "pordenone"
}
},
{
"not": {
"filter": {
"exists": {
"field": "nestedField.province.nome"
}
}
}
}
]
}
},
{
"or": {
"filters": [
{
"term": {
"nestedField.province.comuni.nome": "udine"
}
},
{
"not": {
"filter": {
"exists": {
"field": "nestedField.province.comuni.nome"
}
}
}
}
]
}
}
]
}
}
]
}
}
}
}
}
}
}
文件被退回:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "doc",
"_id": "1",
"_version": 1,
"_score": 1,
"_source": {
"nestedField": [
{
"regione": "Lazio"
},
{
"province": [
{
"nome": "Venezia"
},
{
"nome": "Treviso"
}
],
"regione": "Veneto"
},
{
"province": [
{
"comuni": [
{
"nome": "Varmo",
"parziale": false
}
],
"nome": "Udine"
}
],
"regione": "Friuli venezia giulia"
}
]
}
}
]
}
}
这是所有代码集中在一处:
http://sense.qbox.io/gist/3b187e0fe22651a42501619ff867e02501b81f9e
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.