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

时间:2011-11-15 17:37:48

标签: json elasticsearch nested

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

鉴于以下文档,我如何搜索视频标题中包含“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"
    }
}]

5 个答案:

答案 0 :(得分:45)

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

'video:title': "This is a test title for a video3",
'video:description':"This is my video description3",
'video:url':"/url_of_video3"

您可以搜索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"
      }
    ]
}]

如果您要搜索video.title: 'test' and video.description: 'description2',并且视频未嵌套,则会给您一个假结果(因为test位于第一个视频中,而description2位于第二个视频中,但是在你拥有的所有视频领域中。)

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

答案 1 :(得分:30)

好的,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

希望这可以帮助有人在路上。

答案 2 :(得分:3)

如果您想将其置于Rest API URL格式

  ?

/ _搜索漂亮&安培; Q = video.title:*试验*

答案 3 :(得分:0)

如果嵌套对象的名称唯一,则可以使用后缀.keyword

{
        'query': {
            'term': {
                'title.keyword': "This is a test title for a video"               
            }
        }
}

应与您的第一个示例条目匹配。请注意,video对象名未在任何地方指定。这与所有具有title子对象的对象匹配。

答案 4 :(得分:0)

架构是:

  private schema = {
    id: {
      type: 'integer',
    },
    name: {
      type: 'text',
    },
    tags: {
      type: 'nested',
      properties: {
        id: {
          type: 'integer',
        },
        name: {
          type: 'keyword',
          normalizer: 'useLowercase',
        },
      },
    },
  }

文档结构是

id: 38938
name: "summer fruits"
tags:[
   {
    id : 73
    name: "Grapes"
   },
  {
    id : 74
    name: "Pineapple"
   }
]

搜索查询:

    const { tags } = req.body;

    const { body } = await elasticWrapper.client.search({
        index: ElasticIndexs.Fruits,
        pretty: true,
        filter_path: 'hits.hits._source*',
        body: {
          query: {
            bool: {
              must: tags.map((ele: { name: string }) => {
                return {
                  nested: {
                    path: 'tags',
                    query: {
                      match: {
                        'tags.name': ele.name,
                      },
                    },
                  },
                };
              }),
            },
          },
        },
      });