elasticsearch - 仅在存在嵌套映射时如何应用过滤器

标签 elasticsearch elasticsearch-query

我正在尝试在嵌套 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
        }
      }

关于elasticsearch - 仅在存在嵌套映射时如何应用过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61117385/

相关文章:

elasticsearch - ElasticSearch function_score抛出parsing_exception

elasticsearch - AWS ElasticSearch-匹配查询不起作用

python - 在 python 请求中使用转义引号查询 Elasticsearch

ruby - 如何在带有其gem的ElasticSearch中启用动态脚本?

elasticsearch - 如何在 Elasticsearch DSL 查询中将父聚合键传递给子聚合无痛脚本?

elasticsearch - 查询 Elasticsearch 文档,其中嵌套对象中的属性值为空

python - Boto3 put_object() 很慢

elasticsearch - 如何在ElasticSearch中的单个URI中进行多个搜索查询?

Elasticsearch:可以进行批量搜索吗?

elasticsearch - 在 Elasticsearch 中忽略重复项