【问题标题】:Elasticsearch Geoshape query false resultsElasticsearch Geoshape 查询错误结果
【发布时间】:2016-08-11 04:54:57
【问题描述】:

我在 ES 中有两个 geo_shapes。我需要弄清楚的是了解其中一个形状(绿色)是否包含或与另一个(红色)相交的最佳方法。 请看下面三种不同情况的直观表示:

案例 I:易于检测 - 使用绿色形状坐标进行 Geoshape 查询,“relation” = “within”

案例二:也不是问题 - 使用绿色形状坐标进行 Geoshape 查询,“relation” = “INTERSECTS”

案例 III:是一个真正的问题 - 使用绿色形状坐标我尝试使用“relation”=“INTERSECTS”进行 Geoshape 查询,结果返回红色形状......这是错误的 - 这个形状不相交彼此(我想是的)即使其中一方相互接触......

这里有什么方法可以避免误报结果吗?还有其他如何解决此任务的建议吗?

附:坐标是精确的(例如:13.335594692338)。没有额外的映射,比如 tree_levels 或precision...

【问题讨论】:

  • 我不明白为什么案例 1 使用内部,当红色/绿色多边形彼此相邻(并接触边界的一侧)时。此外,根据定义,案例 3 相交。它们正在接触
  • 案例 1 - 抱歉,我应该让红色变得有点透明......但它在绿色矩形内(绿色矩形与案例 2-3 相同......)关于交叉点 - 同意,但也不同意 - 交叉点是“交叉”......成为某物的边界并不意味着交叉它;)无论如何,一些解决方案将很好地定义交叉和接触)))
  • 很遗憾,ES 不支持通过 'touch' 进行匹配。它只提供 intersect (根据定义,这意味着共享一个共同点,无论它是否交叉。您可能不同意这一点,但这是官方定义。)如果您想要一种解决方法,您可以从 elasticsearch 中获取结果,并且使用 JTS 库,它确实提供了一种触摸方法
  • 这里引用我提到的JTS库:docs.geotools.org/stable/userguide/library/jts/…
  • @coffeeaddict 同意...必须先尝试使用 ES,如果运气不好,可能不得不使用外部工具)))谢谢你的帮助!

标签: elasticsearch elasticsearch-geo-shape


【解决方案1】:

使用 geoshape 存储在 Elasticsearch 中的每个多边形都被转换为字符串列表。 为了缩小这个解释的范围,我假设您在 Elasticsearch 中存储的多边形正在使用 geohash 存储(这是 geoshape 类型的默认值)。

我不想详细介绍,但请看一下这张图片

此描述取自 Elasticsearch 文档(细节不匹配,但您需要了解全局):

Geohashes 将世界划分为一个由 32 个单元组成的网格——4 行和 8 列——每列由一个字母或数字表示。 g 单元格覆盖一半 格陵兰岛、整个冰岛和大不列颠的大部分地区。每个细胞可以 进一步划分为另外32个单元格,可分为 另外 32 个单元格,以此类推。 gc 单元覆盖爱尔兰和英格兰, gcp 覆盖了伦敦的大部分地区和英格兰南部的部分地区,而 gcpuuz94k 是白金汉宫的入口,精确到5米左右。

您的多边形被投影到矩形列表中,每个矩形都用一个字符串 (geohash) 表示。此投影的精度取决于树级别。我不知道 Elasticsearch 的默认树级别是什么,但如果您发现误报,它似乎对您来说太低了。

树级别为 8 splits the world in rectangles of size 38.2m x 19.1m。如果你的多边形的边缘穿过这个矩形的中间,它可能会也可能不会(取决于实现)将此矩形的 geohash 表示分配给你的多边形。

要解决您的问题,您需要提高树级别以满足您的需求(更多关于映射here)。请注意,尽管索引的大小会大大增加(也取决于形状的大小和复杂性)。例如,存储 1000 个区域大小的多边形(有些具有 100 个点),树级别为 8 - 索引大小约为 600-700MB。

请记住,无论您选择什么树级别,您总是冒着得到一些误报的风险,因为 geohash 永远不会 100% 精确地表示您的形状。这是精度与性能的权衡,geohash 是性能明智的选择

【讨论】:

  • 非常感谢您这么详细的解释!!!如果我错了,请纠正我 - 基本上我可以尝试使用“tree_levels”或“precision”并将其设置为“1m”......(PS ES docs建议设置'“tree”:“quadtree”, "precision": "1m" 在我的情况下听起来很合理-也许您可以对此发表评论?)
  • 是的。您应该尝试使用这些值。请记住,每次更改映射时都需要重新索引形状。
  • 非常感谢您的帮助!将尝试使用参数,希望能够获得更精确的结果))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-27
  • 2014-10-22
  • 2018-12-11
  • 2015-08-17
  • 1970-01-01
  • 2014-07-02
  • 2018-06-27
相关资源
最近更新 更多