Elasticsearch:过滤多个嵌套对象数组

时间: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这样的简单方法也必须查询过滤器:

[
            '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字段,则页面过滤器可以正常工作。

我对弹性搜索很陌生,所以如果我做了一些奇怪的假设或做了一些非常错误的事情,请让我知道,这样我就可以学习,如果你需要更多信息,请问问! / p>

1 个答案:

答案 0 :(得分:1)

您的第一个查询似乎没问题。您的分析器和术语查询似乎有问题。术语过滤器在倒排索引中查找完全匹配,即假设主题名称为“幸福”,则英语分析器可将其索引为“快乐”。所以术语过滤器需要索引的确切令牌,在上面的例子中是“快乐”而不是“快乐”。我建议将术语过滤器更改为匹配查询,因为它首先分析字符串,如果它返回结果,请考虑更改分析器或继续使用匹配查询。