{
"blackList":[
{
"inTime":1568719526137,
"relationKey":2,
"relationValue":"957588FF-28B6-4388-B7FB",
"outTime":1571311526137,
"status":1
},
{
"inTime":1568773917483,
"relationKey":3,
"relationValue":"b60407c80d7805db",
"outTime":4102329600000,
"status":1
}
],
"status":1,
"source":1,
"createTime":1568719526137,
"updateTime":1568719526137,
"timestamp":1568719526693
}
上面一条数据,现在要实现一个子查询,要同时满足"relationKey":3,"relationValue":"b60407c80d7805db"才能被查询到
如果是用ES命令行查询的话需要这样写:
GET tmp_list/_search
{
"query": {
"nested": {
"path": "blackList",
"query": {
"bool": {
"must": [
{
"term":{
"blackList.relationKey": {
"value": "3"
}
}
},
{
"term": {
"blackList.relationValue": {
"value": "b60407c80d7805db"
}
}
}
]
}
}
}
}
}
如果在代码中该怎样实现这个功能了?下面是我的踩坑记录。。。。。。
if (null != query.getRelationValue()) {
NestedQueryBuilder nestedQuery = new NestedQueryBuilder("blackList", new TermQueryBuilder("black.relationValue",query.getRelationValue()), ScoreMode.None);
boolQueryBuilder.must(nestedQuery);
}
if (null != query.getRelationKey()) {
NestedQueryBuilder nestedQuery = new NestedQueryBuilder("blackList", new TermQueryBuilder("blackList.relationKey",query.getRelationKey()), ScoreMode.None);
boolQueryBuilder.must(nestedQuery);
}
发现结果虽然是可以查询出来,但是有一个问题就是,查询条件不唯一,假设我把relationKey换成2也可以查询出来同样的数据,后来发现原来是这样写系统会把该代码解析成了或的关系,因为他们不在同一个NestedQueryBuilder里面,只要该节点(List)下面同时含有"relationKey":3和"relationValue":"b60407c80d7805db"(不一定在同一个对象里面),就可以被查询出来。
修改后的代码如下:
BoolQueryBuilder nestedBoolQueryBuilder = QueryBuilders.boolQuery();
if (null != query.getRelationValue()) {
nestedBoolQueryBuilder.must(QueryBuilders.matchQuery("blackList.relationValue", query.getRelationValue()));
}
if (null != queryBlackListPageBo.getRelationKey()) {
nestedBoolQueryBuilder.must(QueryBuilders.matchQuery("blackList.relationKey", query.getRelationKey()));
}
NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("blackList", nestedBoolQueryBuilder, ScoreMode.None);
boolQueryBuilder.must(nestedQueryBuilder);
这样把两个查询条件放到一个NestedQueryBuilder里面,系统就会解析成并且的关系,这样查询出来的结果就是自己想要的了。