仅当存在嵌套映射时如何应用过滤器
How to apply filter only if nested mapping exists
我正在尝试在嵌套 ES 查询上应用位置半径,但嵌套值并非始终存在导致异常
"[nested] nested object under path [contact.address] is not of nested type"
我尝试检查 属性 是否存在然后应用过滤器,但到目前为止没有任何效果
映射如下:
{
"records": {
"mappings": {
"user": {
"properties": {
"user_id": {
"type": "long"
},
"contact": {
"properties": {
"address": {
"properties": {
"city": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"location": {
"properties": {
"lat": {
"type": "long"
},
"lng": {
"type": "long"
},
"lon": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"email": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"properties": {
"first_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"last_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
},
"created_at": {
"type": "date"
}
}
}
}
}
}
有时记录没有位置或地址数据,这会出现问题。示例记录:
{
"contact": {
"name": {
"first_name": "Test",
"last_name": "User"
},
"email": "test@user.com",
"address": {}
},
"user_id": 532188
}
这是我正在尝试的:
GET records/_search
{
"query": {
"bool": {
"must": [
{
"exists": {
"field": "contact.address"
}
},
{
"exists": {
"field": "contact.address.location"
}
}
],
"minimum_should_match": 1,
"should": [
{
"bool": {
"filter": {
"nested": {
"ignore_unmapped": true,
"path": "contact.address",
"query": {
"geo_distance": {
"distance": "50mi",
"contact.address.location": {
"lat": 51.5073509,
"lon": -0.1277583
}
}
}
}
}
}
}
]
}
}
}
您需要使用 nested
数据类型定义正确的映射以避免此问题,看起来动态映射正在产生一些问题。
我用 nested
数据类型定义了自己的映射,即使我错过了嵌套字段中的一些数据,它也不会抱怨。
索引定义
{
"mappings": {
"properties": {
"user_id": {
"type": "long"
},
"contact": {
"type": "nested"
}
}
}
}
索引示例文档
{
"contact": {
"name": {
"first_name": "raza",
"last_name": "ahmed"
},
"email": "opster@user.com",
"address" :{ --> note empty nested field
}
},
"user_id": 123456
}
用嵌套字段中的数据索引另一个文档
{
"contact": {
"name": {
"first_name": "foo",
"last_name": "bar"
},
"email": "opster@user.com",
"address": {
"location" :{. --> note nested data as well
"lat" : 51.5073509,
"lon" : -0.1277583
}
}
},
"user_id": 123456
}
索引另一个文档,它甚至没有空 nested
数据
{
"contact": {
"name": {
"first_name": "foo",
"last_name": "bar"
},
"email": "opster@user.com"
},
"user_id": 123456
}
使用 nested
字段搜索查询
{
"query": {
"nested": {
"path": "contact", --> note this
"query": {
"bool": {
"must": [
{
"exists": {
"field": "contact.address"
}
},
{
"exists": {
"field": "contact.name.first_name"
}
}
]
}
}
}
}
}
搜索结果不会抱怨不包含嵌套文档的文档(给您带来问题的查询)
"hits": [
{
"_index": "nested",
"_type": "_doc",
"_id": "3",
"_score": 2.0,
"_source": {
"contact": {
"name": {
"first_name": "foo",
"last_name": "bar"
},
"email": "opster@user.com",
"address": { --> note the nested doc
"location": {
"lat": 51.5073509,
"lon": -0.1277583
}
}
},
"user_id": 123456
}
}
我正在尝试在嵌套 ES 查询上应用位置半径,但嵌套值并非始终存在导致异常
"[nested] nested object under path [contact.address] is not of nested type"
我尝试检查 属性 是否存在然后应用过滤器,但到目前为止没有任何效果
映射如下:
{
"records": {
"mappings": {
"user": {
"properties": {
"user_id": {
"type": "long"
},
"contact": {
"properties": {
"address": {
"properties": {
"city": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"location": {
"properties": {
"lat": {
"type": "long"
},
"lng": {
"type": "long"
},
"lon": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"email": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"properties": {
"first_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"last_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
},
"created_at": {
"type": "date"
}
}
}
}
}
}
有时记录没有位置或地址数据,这会出现问题。示例记录:
{
"contact": {
"name": {
"first_name": "Test",
"last_name": "User"
},
"email": "test@user.com",
"address": {}
},
"user_id": 532188
}
这是我正在尝试的:
GET records/_search
{
"query": {
"bool": {
"must": [
{
"exists": {
"field": "contact.address"
}
},
{
"exists": {
"field": "contact.address.location"
}
}
],
"minimum_should_match": 1,
"should": [
{
"bool": {
"filter": {
"nested": {
"ignore_unmapped": true,
"path": "contact.address",
"query": {
"geo_distance": {
"distance": "50mi",
"contact.address.location": {
"lat": 51.5073509,
"lon": -0.1277583
}
}
}
}
}
}
}
]
}
}
}
您需要使用 nested
数据类型定义正确的映射以避免此问题,看起来动态映射正在产生一些问题。
我用 nested
数据类型定义了自己的映射,即使我错过了嵌套字段中的一些数据,它也不会抱怨。
索引定义
{
"mappings": {
"properties": {
"user_id": {
"type": "long"
},
"contact": {
"type": "nested"
}
}
}
}
索引示例文档
{
"contact": {
"name": {
"first_name": "raza",
"last_name": "ahmed"
},
"email": "opster@user.com",
"address" :{ --> note empty nested field
}
},
"user_id": 123456
}
用嵌套字段中的数据索引另一个文档
{
"contact": {
"name": {
"first_name": "foo",
"last_name": "bar"
},
"email": "opster@user.com",
"address": {
"location" :{. --> note nested data as well
"lat" : 51.5073509,
"lon" : -0.1277583
}
}
},
"user_id": 123456
}
索引另一个文档,它甚至没有空 nested
数据
{
"contact": {
"name": {
"first_name": "foo",
"last_name": "bar"
},
"email": "opster@user.com"
},
"user_id": 123456
}
使用 nested
字段搜索查询
{
"query": {
"nested": {
"path": "contact", --> note this
"query": {
"bool": {
"must": [
{
"exists": {
"field": "contact.address"
}
},
{
"exists": {
"field": "contact.name.first_name"
}
}
]
}
}
}
}
}
搜索结果不会抱怨不包含嵌套文档的文档(给您带来问题的查询)
"hits": [
{
"_index": "nested",
"_type": "_doc",
"_id": "3",
"_score": 2.0,
"_source": {
"contact": {
"name": {
"first_name": "foo",
"last_name": "bar"
},
"email": "opster@user.com",
"address": { --> note the nested doc
"location": {
"lat": 51.5073509,
"lon": -0.1277583
}
}
},
"user_id": 123456
}
}