索引映射结构
"properties": {
"attrs": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"attrName": {
"type": "keyword",
},
"attrValue": {
"type": "keyword",
}
}
},
....
}
导入数据
例如某一条数据拥有的属性attrs列表如下
需求: 通过多个属性对象(attrId,attrValue)查询同时拥有这些属性对象的目标数据
思路:构建bool查询,过滤或must多个nested嵌套查询,这里需要多个nested是因为一个nested嵌套查询时匹配到的属性对象为单个闭区间,无法访问到其余属性对象。
错误的方式如下:
正确的请求:
json 请求实现
{
"query":{
"bool": {
"filter": [{
"nested": {
"path": "attrs",
"query": {
"bool": {
"must": [
{"term": {"attrs.attrId": {"value": 34}}},
{"term":{"attrs.attrValue": {"value": "培根"}}}
]
}
},
"score_mode": "none"
}},
{
"nested": {
"path": "attrs",
"query": {
"bool": {
"must": [
{"term": { "attrs.attrId": {"value": 41}}},
{"term":{"attrs.attrValue": {"value": "上海外语教育出版社"}}}
]
}
},
"score_mode": "none"
}
}]
}
}}
数据查询成功
java api 实现
if(attrs!=null && attrs.size()>0){
for(String attr : attrs){
BoolQuery.Builder attrValueBoolBuilder=new BoolQuery.Builder();
String[] attrSplit=attr.split("_");
String attrId = attrSplit[0];
String attrValue = attrSplit[1];
attrValueBoolBuilder.must(m->m
.term(t->t
.field("attrs.attrId").value(Long.parseLong(attrId))
)
);
attrValueBoolBuilder.must(m->m
.term(t->t
.field("attrs.attrValue").value(attrValue)
)
);
NestedQuery nestedQuery=NestedQuery.of(n->n
.path("attrs")
.scoreMode(ChildScoreMode.None)
.query(q->q.bool(attrValueBoolBuilder.build())));
boolQueryBuilder.filter(f->f.nested(nestedQuery));
}
}
searchRequestBuilder.query(q->q.bool(boolQueryBuilder.build()));