使用多级嵌套字段进行映射,如下所示:
{
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"
}
]
}
}
即使缺少省字段,查询也找不到给定的记录,如果我们使用" Veneto"它可以正常工作。对于地区和"特雷维索"对于provincia.nome并使用另一个嵌套对象中的comune字段。
为什么这个查询不起作用?
答案 0 :(得分:0)
尝试将您的条款更改为小写。由于您未在映射中指定分析器,因此使用standard analyzer,这会将术语转换为小写。
您的查询非常复杂,起初我认为您可能需要更多"nested"
条款,但是当我执行以下操作时,它似乎有效。 (我确实很快就完成了这个,所以请告诉我,我在这里展示的东西是不是因为某种原因而无法为你工作。)
因为我在"query"
收到错误,我不得不取出"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