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

时间:2015-05-28 09:34:03

标签: search elasticsearch nested

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

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

  • 查找消息我的文字
  • 按消息查找用户

按文字留言(很容易)

它应该如何工作:用户输入“关于会议的注释”,并获得带有此文本的消息列表。

消息存储在ElasticSearch中:

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

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

用户按文字(问题)

它应该如何工作:用户输入“关于会议的注释”,并获得使用此文本编写消息的用户列表。

我几乎没有想法如何组织它,但我真的不喜欢它们中的任何一个。

想法1

查找所有消息,提取其user_id,然后像这样运行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的用户。但也有一些缺点:

  • 添加新邮件时,我必须重新索引整个用户对象
  • 我必须在ElasticSearch缓存中复制消息以提供两种类型的搜索:第一次作为单独的消息对象,第二次作为用户对象中的嵌套对象。我有很多数据(至少有10亿条消息),所以这个重复会使我的缓存非常大(并且可能很慢?)。

你能否告诉我解决这个问题的最佳和最常用的方法?

1 个答案:

答案 0 :(得分:1)

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

您可以使用parent-child relationship解决嵌套对象中可能遇到的问题(请考虑阅读整个部分,尤其是this。)并使用has_childhas_parent个查询根据您的需要。

它将解决索引整个对象的问题。但是你需要考虑内存作为elasticsearch在内存中诅咒子文档id(截至目前)。