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

时间:2017-12-19 13:23:51

标签: elasticsearch

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

{
"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子句中尝试了匹配查询和术语查询,但似乎总是在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子句包装子查询,并添加到父查询,这种方法也不起作用。

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

1 个答案:

答案 0 :(得分: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 中的任何值都设置为"绿色"。要告诉Elasticsearch您想要使用内部对象中的字段之间的关联,您需要将 segment_aggregate' s 类型标记为"嵌套"而不是"对象"的默认值。此外,您还需要使用查询DSL的特殊嵌套查询和嵌套聚合部分。

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