【问题标题】:How do I architect my Elasticsearch indexes for rapidly changing data?如何为快速变化的数据构建 Elasticsearch 索引?
【发布时间】:2016-03-14 14:47:21
【问题描述】:

我的 MySQL 数据库中有两个模型:UsersPosts

users 具有地理位置属性(纬度/经度)

posts 只是有一个正文。

我想使用 Elasticsearch 查找与文本字符串匹配的所有帖子 plus 使用用户的位置作为过滤器。问题是——用户的位置总是在变化(当人们在城市里走动时)。我会经常更新每个用户的纬度/经度。

这是我目前的解决方案:

索引posts 并在每个中都有一个地理位置属性 文档。当用户更改位置时,运行弹性搜索批处理 更新该用户的所有帖子,并修改地理位置属性 在那些文件上。

显然,这不是一个可扩展的解决方案——如果用户有 2000 个帖子并在城市中四处走动怎么办?我必须每分钟更新 2000 个文档。

有没有办法将帖子“关系映射”到用户的对象并将其用作过滤器,这样当位置发生变化时,我只需要更新该用户的对象而不是他的所有帖子?

【问题讨论】:

  • 您能否说明您是仅搜索给定位置附近用户的帖子,还是搜索给定位置附近任何用户的任何帖子?
  • @Val 我想搜索帖子(匹配正文),但在任何给定时间(实时)按用户的位置进行过滤。用户的位置总是在变化。
  • 好的,用户 X 的所有帖子将始终位于该用户当前所在的位置,而不是他创建帖子时所在的位置,对吧?
  • @val - 对 - 他不在的地方(不是在创建帖子时)
  • 谢谢,帖子有一个user_id 字段,其中包含发帖用户的ID,对吧?另一个问题是您的查询是否可能返回来自给定位置周围的不同用户的帖子(+ 由正文过滤)?

标签: elasticsearch lucene


【解决方案1】:

对于update by query 插件或即将推出的reindex API,每分钟更新 2000 个帖子并不是什么大问题。但是,如果您有很多用户有很多帖子,并且您需要在短时间内(例如 1 分钟)更新它们,那么它可能确实没有那么可扩展。假设更新一个用户的所有帖子需要 500 毫秒,那么您将开始落后于大约 120 个用户。

显然,由于用户的帖子需要“关注”用户并且不保留用户发布帖子时的位置,因此我会首先查询给定位置周围的用户并获取他们的 ID,然后运行对按这些用户 ID 和匹配正文过滤的帖子进行第二次查询。

让您的两个索引保持简单并且每分钟只更新单个用户文档中的位置是完全可以的。我建议的这两个查询应该很快,您不必担心运行它们。当人们需要运行两个或更多查询才能找到结果时,他们经常会担心。有时,试图将文档紧密联系在一起并不是解决方案,而简单地对两个索引运行两个查询是关键并且效果很好。

检索用户的查询类似于下面的第一个查询,您只检索用户的_id 属性。我假设您的用户文档将用户的id 作为他们的 ES 文档_id,因此您根本不必检索_source(即"_source": false),它甚至更快并且你可以简单地用response filtering返回_id

POST /users/_search?filter_path=hits.hits._id
{
  "size": 1000,
  "_source": false,
  "query": {
    "bool": {
      "filter": [
        {
          "geo_distance": {
            "distance": "100m",
            "location": {
              "lat": 32.5362723,
              "lon": -80.3654783
            }
          }
        }
      ]
    }
  }
}

您将获得当前在所需地理位置周围 100 米处的用户的所有 _id 值。然后下一个查询包括通过这些 id 过滤帖子,同时匹配它们的正文。

POST /posts/_search
{
  "size": 50,
  "query": {
    "bool": {
      "must": {
        "match": {
          "body": "some text"
        }
      },
      "filter": [
        {
          "terms": {
            "user_id": [ 1, 2, 3, 4 ]
          }
        }
      ]
    }
  }
}

【讨论】:

  • 如果半径是 300 英里,而这个半径内的用户太多了怎么办?
  • 你能定义“太多”(hint as to how many that might be)吗?如果您需要指定 300 英里,那么位置过滤可能不再那么重要了。
猜你喜欢
  • 2013-06-05
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 2014-05-21
  • 2012-12-18
相关资源
最近更新 更多