【问题标题】:Elasticsearch: Filter on multiple arrays of nested objectsElasticsearch:过滤多个嵌套对象数组
【发布时间】:2016-07-19 18:08:08
【问题描述】:

我是 elasticsearch 新手,无法进行所需的查询。我已经阅读了查询、过滤、布尔查询和嵌套对象,但我仍然有点难过。我正在使用 php composer 包进行弹性搜索,但我认为这更多是我的设置问题。

我正在尝试根据对象具有的属性和嵌套对象具有的属性来过滤对象。

我将拥有的示例对象如下:

{
    'id' : '1',
    'title' : 'real catchy title',
    'description' : 'description goes here',
    'content' : [
        'id' : '1',
        'title' : 'foo',
        'subtitle' : 'bar',
        'text' : 'legit full text',
        'sidebar' : 'whatever yo!',
    ],
    'pages' : '12',
    'departments' : [
        {
            'id' : '1',
            'name' : 'foo',
            'description' : 'lorem ipsum'
        },
        {
            'id' : '2',
            'name' : 'bar',
            'description' : 'lorem ipsum'
        }
     ]
    'themes' : [ 
        {
            'id' : '1',
            'name' : 'foo',
            'description' : 'lorem ipsum',
            'month' : '3'
        },
        {
            'id' : '2',
            'name' : 'bar',
            'description' : 'lorem ipsum',
            'month' : '2'
        }
   ]
}

我正在尝试根据页面是否与给定数字匹配,以及它是否具有具有给定部门 ID 的部门以及具有给定主题 ID 的主题来对其进行过滤。

为了做到这一点,我的映射如下:

[
    'index' : ,'reusable_content'
    'body' => [
        'mappings' => [
            'reusable_content' => [
                '_all' => ['analyzer' => 'english'],
                'properties' => [
                    'departments' => [
                        'type' => 'nested', 
                        "include_in_parent" => true
                    ],
                    'themes' => [
                        'type' => 'nested', 
                        "include_in_parent" => true
                    ]
                ]
            ]
        ]
    ]
]

我插入它,然后,我在添加一些条目后尝试了几种方法来查询它。

我尝试过使用布尔嵌套过滤器:

[
            'index' => $this->getIndexName(),
            'type' => 'reusable_content',
            'body' => [
                'query' => [
                    'filtered' => [
                        'query' => ['match_all' => []],
                        'filter' => [
                            'bool' => [
                                'should' => [
                                    'nested' => [
                                        'path' => 'themes',
                                        'filter' => [
                                            'bool' => [
                                                'must' => [
                                                    'term' => [
                                                        'id' => $themeId
                                                    ]
                                                ]
                                            ]
                                        ]
                                    ],
                                    'nested' => [
                                        'path' => 'departments',
                                        'filter' => [
                                            'bool' => [
                                                'must' => [
                                                    'term' => [
                                                        'id' => $departmentId
                                                    ]
                                                ]
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]

这不会返回任何结果。

我也尝试过使用 bool must 查询过滤器等简单方法:

[
            'index' => $this->getIndexName(),
            'type' => 'reusable_content',
            'body' => [
                'query' => [
                    'filtered' => [
                        'query' => ['match_all' => []],
                        'filter' => [
                            'bool' => [
                                'must' => ['term' => ['pages' => $pages]],
                                'must' => ['term' => ['departments.id' => $departmentId]],
                                'must' => ['term' => ['themes.id' => $themeId]],
                            ]
                        ]
                    ]
                ]
            ]
        ]

这主要是有效的,但是它忽略了页面过滤,但是如果我只有 'must' => ['term' => ['pages' => $pages]], 用于过滤器并忽略 id 字段,那么页面过滤器确实有效。

我对弹性搜索还很陌生,所以如果我做出一些奇怪的假设或做错了什么,请告诉我,以便我学习,如果您需要更多信息,请询问!

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您的第一个查询似乎很好。您的分析器和术语查询似乎有问题。术语过滤器在倒排索引中查找完全匹配,即假设主题名称是“快乐”,那么英语分析器可能会将其索引为“快乐”。因此,术语过滤器需要被索引的确切标记,在上述情况下是“快乐”而不是“快乐”。我建议将术语过滤器更改为匹配查询,因为它首先分析字符串,如果返回结果,请考虑更改分析器或继续使用匹配查询。

    【讨论】:

    • 有趣。但是,在我的情况下,页面和 ID 始终是数字。我不希望有任何奇怪的令牌转换。另外,当我单独使用它们中的任何一个时,它们都可以工作,但是当我尝试将所有三个结合起来时,它就不会了。
    • 虽然它们将是数字,但您是否将它们的类型设置为整数?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 2019-12-16
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多