Elasticearch对象属性真的只是带有命名空间的平面属性吗?

lhcgjxsq  于 2022-10-06  发布在  ElasticSearch
关注(0)|答案(1)|浏览(174)

在Elasticearch文档(https://www.elastic.co/guide/en/elasticsearch/reference/current/object.html)中指出,对象属性在内部本质上只是带有命名空间的平面属性。然而,当我这样做时:

POST storage-index/_doc
{
  "person": {
    "lastName":"Miller" 
  },
  "person.lastName":"Smith"
}

该索引包含以下内容:

"_source" : {
      "person" : {
        "lastName" : "Miller"
      },
      "person.lastName" : "Smith"
    }

当我查询这两个都返回文档时,它变得更加奇怪:

对象属性:

POST /storage-index/_search
{
  "query": {
    "query_string": {
      "query": "person.lastName:Miller"
    }
  }
}

平面物业:

POST /storage-index/_search
{
  "query": {
    "query_string": {
      "query": "person.lastName:Smith"
    }
  }
}

我遗漏了什么?

hwazgwia

hwazgwia1#

这个问题的关键是es可以store arrays in any field,这意味着在您的示例中,您在person.lastName中存储了一个数组。

另一个简单的例子是--

让我们创建一个动态Map索引:

PUT my-index-000001/_doc/1
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}

并查看索引GET my-index-000001/_mapping的Map:

{
  "my-index-000001" : {
    "mappings" : {
      "properties" : {
        "manager" : {
          "properties" : {
            "age" : {
              "type" : "long"
            },
            "name" : {
              "properties" : {
                "first" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "last" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                }
              }
            }
          }
        },
        "region" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

manager.name.firstmanager.name.last完全相同。

让我们使用您问题中的格式添加另一个文档:

PUT my-index-000001/_doc/2
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "Lucy",
      "last":  "James"
    },
    "name.first": "Kate"
  }
}

那么,猜猜现在索引的Map是什么?它是否添加了额外的manager.name.first?不是的。Map不会更改。它现在只是一个与数组一起存储的字段,而不是单个对象。

上面的文档将两个名字存储为一个数组,因此它与下一个文档完全相同:

PUT my-index-000001/_doc/3
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": [
      { 
        "first": "Lucy",
        "last":  "James"
      },
      { 
        "first": "Kate"
      }
    ]
  }
}

原始格式看似不同,但底层存储没有区别:

{
  "region" :        "US",
  "manager.age":    30,
  "manager.name.first" : [ "Lucy", "Kate" ],
  "manager.name.last" :  "James"
}

查询方式:

GET my-index-000001/_search
{
  "query": {
    "match": {
      "manager.name.first": "kate"
    }
  }
}

它们都将被选中:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.43445712,
    "hits" : [
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.43445712,
        "_source" : {
          "region" : "US",
          "manager" : {
            "age" : 30,
            "name" : {
              "first" : "Lucy",
              "last" : "James"
            },
            "name.first" : "Kate"
          }
        }
      },
      {
        "_index" : "my-index-000001",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.43445712,
        "_source" : {
          "region" : "US",
          "manager" : {
            "age" : 30,
            "name" : [
              {
                "first" : "Lucy",
                "last" : "James"
              },
              {
                "first" : "Kate"
              }
            ]
          }
        }
      }
    ]
  }
}

但只是显示为它们的原始格式。

编辑:关于为什么总是返回原始格式,请参见:_source。如果搜索时其他字段没有指定,则ElasticSearch只返回原始的_source

相关问题