ElasticSearch - 布尔查询过滤器问题

Posted

技术标签:

【中文标题】ElasticSearch - 布尔查询过滤器问题【英文标题】:ElasticSearch - Problem with filter on Boolean query 【发布时间】:2020-09-11 14:42:40 【问题描述】:

我在布尔查询中遇到过滤器问题。

我想应用基于 3 个字段和 1 个最小过滤器匹配的过滤器:

$params = [
    'from' => 0,
    'size' => 25,
    'index' => 'document',
    'body' => [
        'query' => [
            'bool' => [
                'filter' => [
                    'bool' => [
                        'minimum_should_match' => 1,
                        'should' => [
                            'term' => [
                                'VISIBILITE' => 'T'
                            ],
                            'term' => [
                                'ECRITURE' => 'M'
                            ],
                            'term' => [
                                'LECTURE' => 'M'
                            ],
                        ]
                    ]
                ],
                'must' => [
                    [
                        'bool' => [
                            'should' => [ 
                                [
                                    'match' => [
                                        'OBJET' => $recherche,
                                    ]
                                ],
                            ] 
                        ]
                    ],
                ],
            ],
        ],
    ],
];

我没有得到这个查询的结果,但是我在索引中看到了很多相关的文档。


Opster Elasticsearch Ninja 测试:

例如你向我提出的1,我有很多结果返回。

但是,当我想对 OBJECT 字段执行必须查询时,我没有得到与过滤器完美匹配的相同结果。

这是一个例子:

    仅使用 must 子句进行搜索

    "took": 8,
    "timed_out": false,
    "_shards": 
        "total": 2,
        "successful": 2,
        "skipped": 0,
        "failed": 0
    ,
    "hits": 
        "total": 
            "value": 1268,
            "relation": "eq"
        ,
        "max_score": 13.616098,
        "hits": [
            
                "_index": "document",
                "_type": "_doc",
                "_id": "26685",
                "_score": 13.616098,
                "_source": 
                    "NUMDOCUMENT": "26685",
                    "TYPEDOCUMENT": "Proc\u00e9dure",
                    "OBJET": "Proc\u00e9dure d'importation des index dans Marco 2",
                    "MOTCLES": "",
                    "LECTURE": "S",
                    "VISIBILITE": "T", // Must match on second search
                    "ECRITURE": "M" // Must match on second search
                
            
        ]
    

    使用 must 子句和过滤器进行搜索

    "took": 9,
    "timed_out": false,
    "_shards": 
        "total": 2,
        "successful": 2,
        "skipped": 0,
        "failed": 0
    ,
    "hits": 
        "total": 
            "value": 10000,
            "relation": "gte"
        ,
        "max_score": 0,
        "hits": [
            
                "_index": "document",
                "_type": "_doc",
                "_id": "431",
                "_score": 0,
                "_source": 
                    "NUMDOCUMENT": "431",
                    "TYPEDOCUMENT": "Document",
                    "OBJET": "Diagnostic informatique SAFC",
                    "LECTURE": "M",
                    "VISIBILITE": "T",
                    "ECRITURE": "M"
                
            
        ]
    

它不再是首先出现的同一个文档(尽管该文档对应于过滤器)。就好像搜索过滤器会影响搜索必须的分数和相关性。

【问题讨论】:

介意分享一些这些文档和您的索引映射吗? 没有must 部分是否可以工作? 很高兴您能找到解决方案,如果有帮助,请不要忘记给我的答案投票 :), 【参考方案1】:

问题似乎与您的 bool 查询有关,如果您在顶层查看您的查询,您有两个构造

    具有 3 个应该条件的过滤器块,其中至少 1 个应该匹配,这将过滤即减少将执行下一个 must 子句的文档集。

    必须阻止,我怀疑在步骤 1 中减少的文档集上没有匹配任何内容,这会导致您的查询不返回任何内容。

为了调试问题,您应该独立尝试第一个块,然后在合并时查看是否得到结果,因为您的 must 块没有正确的数据,我在下面创建显示您是否有正确数据的示例,它会返回数据:


    "query": 
        "bool": 
            "should": [
                
                    "term": 
                        "VISIBILITE": "T"
                    
                ,
                
                    "term": 
                        "ECRITURE": "T"
                    
                ,
                
                    "term": 
                        "LECTURE": "T"
                    
                
            ],
            "minimum_should_match": 1
        
    

搜索查询结果,显示匹配文档的_source

"hits": [
            
                "_index": "minshouldmatch",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.5686158,
                "_source": 
                    "VISIBILITE": "T", 
                    "ECRITURE": "T",
                    "LECTURE": "T"
                
            ,
            
                "_index": "minshouldmatch",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.18232156,
                "_source": 
                    "VISIBILITE": "T", // note even only 1 condition matches still it comes in SR
                    "ECRITURE": "M",
                    "LECTURE": "M"
                
            
        ]

【讨论】:

感谢您的回复!我在之前的请求之后添加了测试和解释。【参考方案2】:

我找到了解决方案。我忘记了应该过滤器的钩子。

不好:

'bool' => [
                'filter' => [
                    'bool' => [
                        'minimum_should_match' => 1,
                        'should' => [
                            'term' => [
                                'VISIBILITE' => 'T'
                            ],
                            'term' => [
                                'ECRITURE' => 'M'
                            ],
                            'term' => [
                                'LECTURE' => 'M'
                            ],
                        ]
                    ]
                ],

好:

'bool' => [
                'filter' => [
                    'bool' => [
                        'minimum_should_match' => 1,
                        'should' => [[ // Double hook
                            'term' => [
                                'VISIBILITE' => 'T'
                            ],
                            'term' => [
                                'ECRITURE' => 'M'
                            ],
                            'term' => [
                                'LECTURE' => 'M'
                            ],
                        ]]
                    ]
                    
                ],

【讨论】:

以上是关于ElasticSearch - 布尔查询过滤器问题的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch (DSL 布尔查询 过滤器 排序 高亮显示

Elasticsearch查询类型

ElasticSearch 常用的查询过滤语句

ElasticSearch 常用的查询过滤语句

ElasticSearch 常用的查询过滤语句

ElasticSearch结构化查询