复杂类型对象字段上的ElasticSearch AND操作

问题描述 投票:0回答:1

我有一个弹性搜索索引,其中包含以下映射:

{
"index_one": {
    "mappings": {
        "uidMapping": {
            "_all": {
                "enabled": false
            },
            "_source": {
                "enabled": false
            },
            "properties": {
                "age": {
                    "type": "keyword"
                },
                "clean_url": {
                    "type": "keyword",
                    "index": false,
                    "fields": {
                        "hash": {
                            "type": "murmur3"
                        }
                    }
                },
                "gender": {
                    "type": "keyword"
                },
                "segment_aggregate": {
                    "properties": {
                        "segment_name": {
                            "type": "keyword"
                        },
                        "segment_value": {
                            "type": "keyword"
                        }
                    }
                },
                "url_md5": {
                    "type": "keyword",
                    "index": false
                },
                "url_page_views": {
                    "type": "integer",
                    "index": false
                }
            }
        }
    }
}
}

我试图在segment_aggregate字段上运行带有AND操作的查询,即只有在满足两个条件时才返回查询结果。到目前为止,使用BoolQueryBuilders,我在Must子句中尝试了Match查询和术语查询,但似乎总是在segment_name和segment_value之间获得或运算结果。

 BoolQueryBuilder queryTest = new BoolQueryBuilder();  
 queryTest.must(QueryBuilders.matchQuery("segment_aggregate.segment_name", 
 "AnyValue").operator(Operator.AND));

queryTest.must(QueryBuilders.matchQuery("segment_aggregate.segment_value", 
"A").operator(Operator.AND));

parentQuery.must(queryTest);

这将返回两个字段的OR结果,基本上是较大的子集。也试过:

mustQuery.must(QueryBuilders.termsQuery("segment_aggregate.segment_name", "SegmentName"));
mustQuery.must(QueryBuilders.termsQuery("segment_aggregate.segment_value", "SegmentValue"));

这也不会产生欲望的结果。即使我尝试在另一个查询中使用must子句包装子查询,并添加到父查询,这种方法也不起作用。

关于我哪里出错的任何想法?

elasticsearch
1个回答
1
投票

您看到的问题可能是因为您没有将segment_aggregate类型标记为嵌套。

默认情况下,所有字段都是独立索引的。尽管JSON结构看起来像是将segment_aggregate中的内部对象内的特定值关联在一起,但实际上ES正在为segment_aggregate.segment_name创建值的索引,并为segment_aggregate.segment_value创建单独的索引。

这意味着当你进行这样的搜索时(假设查询字符串):

segment_aggregate.segment_name:color AND segment_aggregate.segment_value:green 

Elasticsearch实际上在做的是搜索一个文档,其中segment_aggregate.segment_name中的任何值都设置为“color”,而segment_aggregate.segment_value中的任何值都设置为“green”。要告诉Elasticsearch您想要使用内部对象中的字段之间的关联,您需要将segment_aggregate的类型标记为“嵌套”而不是默认的“对象”。此外,您还需要使用查询DSL的特殊嵌套查询和嵌套聚合部分。

更多细节可以在这里找到:https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

© www.soinside.com 2019 - 2024. All rights reserved.