【问题标题】:Missing geo_point fields in elasticsearch response弹性搜索响应中缺少 geo_point 字段
【发布时间】:2016-01-12 23:28:56
【问题描述】:

如果使用“fields []”指定,结果中似乎忽略了 geo_point 字段

我有以下索引 test01 的映射

{
   "test01": {
      "mappings": {
         "activity": {
            "properties": {
               "location": {
                  "type": "string"
               },
               "mygeo": {
                  "type": "geo_point",
                  "doc_values": true,
                  "fielddata": {
                     "format": "compressed",
                     "precision": "1km"
                  }
               }
            }
         }
      }
   }
}

索引包含单个活动

{
      "mygeo": {
        "lat": 51.247607909,
        "lon": 22.565701278
      },
      "location" : "New York"
}

查询

GET /test01/_search
{
  "size" : 1,
  "fields": ["location", "mygeo"]
}

在缺少 mygeo 字段的地方生成以下内容。 (我也尝试过“字段”:[“location”,“mygeo.lat”,“mygeo.lon”,“mygeo”])。

 "hits": [
     {
        "_index": "test01",
        "_type": "activity",
        "_id": "1",
        "_score": 1,
        "fields": {
           "location": [
              "New York"
           ]
        }
     }
  ]

获取 mygeo 对象的唯一方法是通过 _source 添加 "_source" : {"includes" : [ "mygeo" ]}。

有没有办法使用“field”参数获取geo_point字段?

我已经尝试过 Rest API 和 Java API。两者都使用 Elasticsearch v. 1.7.1 产生相同的结果。

谢谢

【问题讨论】:

    标签: elasticsearch field geopoints


    【解决方案1】:

    因此,按照逻辑,我通过将"store": true 添加到您的索引映射中来复制并解决了该问题,现在它允许我使用fields 而不是_source 检索经度/纬度。

    请在我的本地主机上查看在Sense 上完成的复制:

    DELETE test
    
    PUT /test
    {
      "mappings": {
        "test1": {
          "properties": {
            "location": {
              "type": "string"
            },
            "mygeo": {
              "type": "geo_point",
              "doc_values": true,
              "store": true, 
              "fielddata": {
                "format": "compressed",
                "precision": "1km"
              }
            }
          }
        }
      }
    }
    
    POST /test/test1/
    {
      "mygeo": {
        "lat": 51.247607909,
        "lon": 22.565701278
      },
      "location": "New York"
    }
    
    
    GET /test/_search
    {
      "size" : 1,
      "fields": ["location", "mygeo"]
    }
    

    因此,此查询确实会返回您所期望的结果。唯一的问题是您的 lan/lon 被格式化为数组。查看查询结果:

    {
      "hits" : [{
          "_index" : "test",
          "_type" : "test1",
          "_id" : "AVCGqhsq9y2W0mh1rPgV",
          "_score" : 1,
          "fields" : {
            "mygeo" : [
              "51.247607909,22.565701278"
            ],
            "location" : [
              "New York"
            ]
          }
        }
      ]
    }
    

    不过,这是 Elasticsearch 官方支持的格式之一。取自documentation

    将 location 字段定义为 geo_point,我们可以继续 包含纬度/经度对的索引文档,可以是 格式化为字符串、数组或对象:

    PUT /attractions/restaurant/1
    {
      "name" : "Chipotle Mexican Grill",
      "location" : "40.715, -74.011"
    }
    
    PUT /attractions/restaurant/2
    {
      "name" : "Pala Pizza",
      "location" : {
        "lat" : 40.722,
        "lon" : -73.989
      }
    }
    
    PUT /attractions/restaurant/3
    {
      "name" : "Mini Munchies Pizza",
      "location" : [-73.983, 40.719]
    }
    

    另外,请在文档中注意这一点:

    每个人都至少被抓到一次:字符串地理点是 “纬度,经度”,而数组地理点是 [longitude,latitude]——相反的顺序!

    【讨论】:

    • 奇怪,因为我没有收到此错误。至少如果 mygeo 在映射模板中实际声明为 geo_point 则不会。然后 mygeo 根本不会返回而没有任何错误。我知道非叶节点不能通过字段返回,但 mygeo.lat 和 mygeo.lon 也不会返回,也不会引发错误。
    • 显然我在那里的代码中有错字。我映射的 geo_type 不正确,数据作为字符串插入,但我想我找到了如何让它工作。我已经更新了答案
    • 这按应有的方式工作。非常感谢。知道为什么必须为 geo_point 类型设置 "store": true 吗?
    • 我发现了关于 SO 讨论为什么需要将 "store" 设置为 true 的问题。也许它会解释它? stackoverflow.com/questions/17103047/… 很遗憾,我不能自己回答这个问题。
    【解决方案2】:

    如果您的字段存储在 _source 中(即使它是 GeoPoint 类型字段),您必须使用“_source”查询参数来指定您想要哪些字段(来自源):

    GET /_search
    {
        "_source": "obj.*",
        "query" : {
            "term" : { "user" : "kimchy" }
        }
    }
    

    在此处查看更多详细信息:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html

    长话短说:

    • 如果您的字段在源中,那么您需要在查询中指定“_source”模式以仅获取您想要的部分(字段)
    • 在查询中指定“字段”(大部分情况下)对于在映射中使用“store: yes”声明的字段是有意义的。这并没有说明应该从源返回哪些字段。
    • 是的,这里有一个不一致的地方:如果您的字段在源中映射,但没有用“Store: yes”声明,那么在查询的“fields”参数中指定它可能会也可能不会返回它(我已经注意到在这种情况下会返回“简单”字段,例如文本、数字等,但不会返回更复杂的字段(例如时间戳或 GeoPoint)。

    【讨论】:

      猜你喜欢
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多