如何使用弹性搜索搜索嵌套对象

swa*_*ins 37 json nested elasticsearch

好吧,到目前为止我还没弄清楚这一点.希望有人可以提供一些见解.

鉴于以下文档,我如何搜索视频标题中包含"test"的视频的所有文档?我正在使用HTTP API. (基本上,你如何使用弹性搜索搜索嵌套对象?我知道那里必须有文档,但我真的找不到任何文档.)

[{
    id:4635,
    description:"This is a test description",
    author:"John",
    author_id:51421,
    video: {
        title:"This is a test title for a video",
        description:"This is my video description",
        url:"/url_of_video"
    }
},
{
    id:4636,
    description:"This is a test description 2",
    author:"John",
    author_id:51421,
    video: {
        title:"This is an example title for a video",
        description:"This is my video description2",
        url:"/url_of_video2"
    }
},
{
    id:4637,
    description:"This is a test description3",
    author:"John",
    author_id:51421,
    video: {
        title:"This is a test title for a video3",
        description:"This is my video description3",
        url:"/url_of_video3"
    }
}]
Run Code Online (Sandbox Code Playgroud)

dir*_*ira 51

你不一定需要嵌套视频; 您可以将其映射为普通字段.这意味着它将存储

'video:title': "This is a test title for a video3",
'video:description':"This is my video description3",
'video:url':"/url_of_video3"
Run Code Online (Sandbox Code Playgroud)

你可以搜索video.title:'test'.

据我所知,当您有多个嵌套项时,嵌套字段很有用,并且您只想对嵌套项进行查询.例如,拥有此数据

[{
    id:4635,
    description:"This is a test description",
    author:"John",
    author_id:51421,
    video: [
      {
        title:"This is a test title for a video",
        description:"This is my video description",
        url:"/url_of_video"
      },
      {
        title:"This is an example title for a video",
        description:"This is my video description2",
        url:"/url_of_video2"
      }
    ]
},
{
    id:4637,
    description:"This is a test description3",
    author:"John",
    author_id:51421,
    video: [
      {
        title:"This is a test title for a video3",
        description:"This is my video description3",
        url:"/url_of_video3"
      }
    ]
}]
Run Code Online (Sandbox Code Playgroud)

如果你要搜索video.title: 'test' and video.description: 'description2',并且视频没有嵌套,它会给你一个假的结果(因为test在第一个视频和description2第二个视频中,但在所有视频领域你都有).

在这种情况下,如果您将视频映射为嵌套,它会将每个视频记录为一个单独的实体,并将搜索符合这些条件的单个视频,因此video.title: 'test' and video.description: 'description2'它将不返回任何内容,因为video.title: 'example' and video.description: 'description2'它将返回一个结果.

  • 这个答案提供了嵌套和简单存储子数组或对象之间的重要区别.嵌套在一个索引中创建额外的文档,并在@swatkins案例中不必要地使事情复杂化. (6认同)

swa*_*ins 33

好的,RTFM!我终于找到了这些页面(应该花费更多的时间预先使用文档)并且似乎我们设置了保存视频的属性:嵌套,然后使用嵌套查询.

http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html

希望这有助于有人在路上.

  • 评论中的链接已损坏 (3认同)
  • 您不一定需要嵌套视频。请参阅 http://www.elasticsearch.org/blog/2010/02/12/yourdatayoursearch.html 和我在下面的回答。 (2认同)
  • 我发现这篇博文也很有帮助:http://www.elasticsearch.org/blog/managing-relations-inside-elasticsearch/ (2认同)

小智 8

如果你想把它放在 Rest API URL 格式

/_search?pretty&q=video.title:*test*


小智 5

给出一个更通用的答案:

  • 如果一次搜索一个字段,请使用对象(无嵌套)。这是因为在内部,字段被展平,如下所示:

Elasticsearch 中的对象

  • 如果您需要在多个字段中搜索(例如title:test AND description:my),请使用嵌套,因为对象不关心边界。同时,嵌套字段在底层创建单独的 Lucene 文档,并通过 Lucene 的 BlockJoin 快速连接:

Elasticsearch 中的嵌套字段

  • 如果您在多个字段中搜索并经常更新子文档(因为嵌套文档的更新将更新整个集合),请使用父子关系(在不同的 Elasticsearch 文档之间)。基本上,如果您想用查询性能来换取更新性能,因为查询在后台分两个步骤运行:

Elasticsearch 有子查询

注:上图来自 Sematext 的Elasticsearch 培训课程(披露:这些课程是我讲授的)。