3

我找不到使用 ElasticSearch 执行以下操作的方法:

  • 我在 ElasticSearch 中索引了 2,000,000 个项目
  • 我在 MySQL 中保存了 30,000 名玩家

每个项目都有一个玩家的名字作为属性。这些玩家的在线状态每 15 分钟更改一次,并且可以是真或假(显然)。

我希望能够只显示在线玩家的项目。

我不认为我可以用该项目索引在线状态,因为它经常变化。我无法真正获取在线玩家的所有 id 并将其用作过滤器,因为有这么多。

对 ElasticSearch 中的玩家进行索引是否也有帮助?JOIN是否可以对另一个索引进行某种操作?

编辑:在更多地研究了如何使用 ES 进行连接之后,我发现如果我在 ES 中索引玩家,实际上可以使用 has_child。Tire 没有方法has_child,但是可以用现有的 DSL 来做吗?

4

1 回答 1

2

似乎很适合玩家和物品之间的父子关系,即使您不需要在父文档上进行全文搜索,因为:

  1. 每个项目都属于一个玩家
  2. 他们有独立的更新生命周期:当一个玩家改变时,你不想重新索引他的所有项目
  3. 您只想返回孩子,对他们的父母应用过滤器。

您也可以在与项目相同的索引中但在单独的类型中索引您的玩家。您需要在映射中声明播放器类型是项目类型的项:

{
  "item":{
    "_parent":{
      "type" : "player"
    }
  }
}

之后,您索引玩家,然后您的项目为每个玩家指定父玩家 ID。

然后,您可以对项目执行全文搜索,使用以下has_parent 过滤器过滤它们。

{
    "has_parent" : {
        "parent_type" : "player",
        "query" : {
            "term" : {
                "status" : true
            }
        }
    }
}

这样,您只会查询并最终返回属于活动玩家的项目。

为了更新播放器,您可以使用更新 API,也可以使用脚本来避免重新发送整个文档。请注意,无论如何,文档都将被删除并重新索引,这就是 lucene 的工作原理。

如果您想查看更多有关 elasticsearch 中文档之间关系的示例,请查看以下文章:

根据您需要的查询类型,您可能会遇到限制,但鉴于您所写的内容,这就是我会做的。只需确保您的节点有足够的内存,因为 elasticsearch 在内存中保留了一个连接表,其中包含使用父子节点时涉及的所有 id。

于 2013-04-20T16:38:20.950 回答