如何使用 ElasticSearch 组织嵌套对象的搜索?

How to organize a search of nested objects with ElasticSearch?

我正在尝试使用 ElasticSearch 在我的项目中组织搜索,但无法弄清楚一件事。

让我们简化上下文并假设有 2 个模型:用户及其消息。所以,我想提供两种类型的搜索:

短信消息(很简单)

它应该如何工作:用户输入 "notes about the meeting" 并且他会得到包含此文本的消息列表。

消息是这样存储在 ElasticSearch 中的:

{
  "id" : "1",
  "user_id" : "101",
  "text": "hello"
}

因此,通过文本查找消息没有问题。

用户文本(问题)

它应该如何工作:用户输入 "notes about the meeting" 并且他会得到一个使用此文本编写消息的用户列表。

我不知道如何组织它,但我真的不喜欢它们中的任何一个。

想法 1

找到所有的消息,提取它们的 user_ids 然后 运行 SQL 像这样查询

SELECT * FROM users WHERE id IN ('101', '102', '103')

这是最明显的方法,但有一个问题——如何组织适当的分页?消息是分页的,但用户不是。

想法 2

将用户的消息作为嵌套对象存储在 ElasticSearch 中:

{ 
  "id" : "101",
  "name" : "Bob",
  "messages" : [
    { "id" : "1", "text" : "hello" },
    { "id" : "2", "text" : "howdy?" },
    { "id" : "3", "text" : "bye" }
  ]
}

现在我可以通过ElasticSearch 一次查询找到用户。但是也有一些缺点:

你能建议我最好和最常用的解决这个问题的方法吗?

正如您所指出的,可以通过使用嵌套对象来解决,但更好的方法是使用父子关系。

您在嵌套对象中可能遇到的问题可以根据您的需要使用 parent-child relationship(consider reading the whole section especially this.) and use has_child or has_parent 查询来解决。

它将解决需要索引整个对象的问题。但是您需要考虑内存,因为 elasticsearch 在内存中存储子文档 ID(截至目前)。