为什么在索引形状和查询形状相同的 geoshape 查询中使用“contains”和“within”时,elasticsearch 会返回不同的结果?

问题描述 投票:0回答:0

考虑以下几点:

我有一个包含 geoshape 字段的索引。 geoshape 可以代表任何东西,但作为一个例子,我们可以考虑索引形状是一个矩形:

我们正在使用名为

location
:

的 geoshape 字段创建索引
PUT /example
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_shape"
      }
    }
  }
}

我们在

location
字段中索引一个包含矩形的文档:

POST /example/_doc
{
  "location" : {
    "type": "polygon",
    "coordinates": [
      [
        [
          -1.738392029727578,
          52.3042810657775
        ],
        [
          -1.738392029727578,
          51.81371529802078
        ],
        [
          0.694240708108822,
          51.81371529802078
        ],
        [
          0.694240708108822,
          52.3042810657775
        ],
        [
          -1.738392029727578,
          52.3042810657775
        ]
      ]
    ]
  }
}

我们使用具有内联形状定义的 geoshape 查询来搜索索引(指定的关系将是

within
):

GET /example/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "geo_shape": {
          "location": {
            "shape": {
              "type": "polygon",
              "coordinates": [
                [
                  [
                    -1.738392029727578,
                    52.3042810657775
                  ],
                  [
                    -1.738392029727578,
                    51.81371529802078
                  ],
                  [
                    0.694240708108822,
                    51.81371529802078
                  ],
                  [
                    0.694240708108822,
                    52.3042810657775
                  ],
                  [
                    -1.738392029727578,
                    52.3042810657775
                  ]
                ]
              ]
            },
            "relation": "within"
          }
        }
      }
    }
  }
}

返回的结果如下(与先前索引文档中存在的相同形状):

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "example",
        "_id": "EO3gAIgBN8DGPp9VobXP",
        "_score": 1,
        "_source": {
          "location": {
            "type": "polygon",
            "coordinates": [
              [
                [
                  -1.738392029727578,
                  52.3042810657775
                ],
                [
                  -1.738392029727578,
                  51.81371529802078
                ],
                [
                  0.694240708108822,
                  51.81371529802078
                ],
                [
                  0.694240708108822,
                  52.3042810657775
                ],
                [
                  -1.738392029727578,
                  52.3042810657775
                ]
              ]
            ]
          }
        }
      }
    ]
  }
}

如果我们要将空间关系从

within
更改为
contains

GET /example/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "geo_shape": {
          "location": {
            "shape": {
              "type": "polygon",
              "coordinates": [
                [
                  [
                    -1.738392029727578,
                    52.3042810657775
                  ],
                  [
                    -1.738392029727578,
                    51.81371529802078
                  ],
                  [
                    0.694240708108822,
                    51.81371529802078
                  ],
                  [
                    0.694240708108822,
                    52.3042810657775
                  ],
                  [
                    -1.738392029727578,
                    52.3042810657775
                  ]
                ]
              ]
            },
            "relation": "contains"
          }
        }
      }
    }
  }
}

我们没有得到任何结果:

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

如果我们使用预先索引的形状尝试这种方法,情况也是如此:

GET /example/_search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "geo_shape": {
          "location": {
            "indexed_shape": {
              "index": "example",
              "id": "EO3gAIgBN8DGPp9VobXP",
              "path": "location"
            },
            "relation": "within"
          }
        }
      }
    }
  }
}

我将跳过添加返回的结果,因为它与之前呈现的结果相同。

来自 Elasticsearch 文档:

WITHIN - 返回其 geo_shape 或 geo_point 字段在查询几何图形内的所有文档。不支持线几何。

包含 - 返回其 geo_shape 或 geo_point 字段包含查询几何的所有文档。

由于

geo_shape
字段包含与作为查询几何(内联形状定义或预索引形状)传递的几何相同的信息,查询结果为何不一致?对于这两种情况,它应该要么不返回任何结果,要么返回相同的文档。

显然,尝试检查各种论坛是否存在类似问题:github issues、https://discuss.elastic.co、stack overflow 等

我会试着看一下源代码,但我怀疑我能从那里理解一些东西。

elasticsearch gis geospatial spatial-query elasticsearch-geo-shape
© www.soinside.com 2019 - 2024. All rights reserved.