1、查询有两种方案:
(1)先过滤条件,再搜索关键字
(2)先搜索关键字,再过滤条件
采用先过滤条件,再搜索关键字,这样查询效率更高!!!
2、这样的查询也是交集查询,把查询范围缩小,才能更加符合用户需查询的商品。
query{
bool #联合查询
filter #过滤条件
term #过滤某一列的id
must #关键字查询
match #搜索某一列数据的关键字
}
3、举例,执行下面的es复杂查询(过滤条件+关键字查询)(filter过滤条件term交集):
GET gmall0105/PmsSkuInfo/_search
{
"query": {
"bool": {
"filter": [
{ "term": {"skuAttrValueList.valueId":"47"}
},
{"term": {"skuAttrValueList.valueId": "93"}
}
]
, "must": [
{
"match": {
"skuName": "小米"
}
}
]
}
}
}
注意这里的filter过滤条件的大括号格式:
“filter”:[
{ “term”:{} } ,
{ “term”:{} }
]
4、执行下面的es复杂查询(过滤条件+关键字查询)(filter过滤条件terms并集)
这个terms并集的过滤条件范围比term大,所以按照terms过滤。
代码如下:
GET gmall0105/PmsSkuInfo/_search
{
"query": {
"bool": {
"filter": [
{"terms":{"skuAttrValueList.valueId":["62","68","83"]}
},
{ "term": {"skuAttrValueList.valueId":"47"}
},
{"term": {"skuAttrValueList.valueId": "93"}
}
]
, "must": [
{
"match": {
"skuName": "小米"
}
}
]
}
}
}
5、查询结果,数据库总共12条小米sku商品,查询到符合条件的共7条:
6、既然知道es的复杂查询语句,并且测试也查到了相应的结果,接下来就是对接在java层面,对es进行查询。难度系数巨高!!!认真理解!!!
(1)new一个Search.Builder对象(“es查询语句”).addIndex索引.addType表名.buid()
Search search = new Search.Builder("").addIndex("gmall0105").addType("PmsSkuInfo").build();
(2)使用jestClient.execute(search)对其进行包装和解析,并返回结果:
返回的结果是这样的,有很多参数,我们需要对这些参数进行处理,需要用哪个参数?
(3)这里就暂时使用hits匹配条数吧,接收回来的结果result.getHits(映射类的class泛型),快捷键Ctrl+alt+v,使用一个泛型列表接收它。
(4)再把这个泛型列表数据使用for循环遍历每一条数据hit.source,最终得到就是你需要的对象数据了,再使用一个es对象列表接收即可!
//用api执行es复杂查询
List<PmsSearchSkuInfo> pmsSearchSkuInfos = new ArrayList<>();
Search search = new Search.Builder("{\n" +
" \"query\": {\n" +
" \"bool\": {\n" +
" \"filter\": [\n" +
" {\"terms\":{\"skuAttrValueList.valueId\":[\"62\",\"68\",\"83\"]}\n" +
" },\n" +
" \n" +
" { \"term\": {\"skuAttrValueList.valueId\":\"47\"}\n" +
" },\n" +
" \n" +
" {\"term\": {\"skuAttrValueList.valueId\": \"93\"}\n" +
" }\n" +
" \n" +
" ]\n" +
" \n" +
" , \"must\": [\n" +
" {\n" +
" \"match\": {\n" +
" \"skuName\": \"小米\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
"}").addIndex("gmall0105").addType("PmsSkuInfo").build();
SearchResult result = jestClient.execute(search);
List<SearchResult.Hit<PmsSearchSkuInfo, Void>> hits = result.getHits(PmsSearchSkuInfo.class);
for (SearchResult.Hit<PmsSearchSkuInfo, Void> hit : hits) {
pmsSearchSkuInfos.add(hit.source);
}
System.out.print(pmsSearchSkuInfos.size());
7、断点测试,查询到es条数7条,测试成功:
这样查询,虽然可以,但是这个es查询语句(json的dsl语句)太长了,直接粘贴在代码里,显得非常冗肿。
8、使用jest的dsl工具,帮助我们写es查询语句
分页:
1、前台传递页码,
2、定义每页多少条数,
3、条数*页码 就是你查询的范围
(1)
复杂条件查询语句:
query 查询
bool 联合查询
filter 过滤条件
terms 过滤某一列的id的并集
term 过滤某一列的id
must 关键字查询
match 搜索某一列数据的关键字
from
size
highlight
(2)步骤,记得上边的单词即可,并且理解其的层级关系,下面的代码就很好写了:
(3)New searchsourcebuilder对象,这个对象下有query、from、size、highlight这些方法同级
(4)New boolquerybuilder对象,这个对象有filter、must这些方法同级
(5)New termquerybuilder对象,有term方法,填写(“字段名”,“值”),筛选id。
(6)如果多个id并集筛选,则new termsquerybuilder对象
(7)New matchquerybuilder对象,有match方法,填写(“字段名”,“值”),搜索关键字
如果要完整的查询一次有过滤列和关键字的搜索,需要4个new对象,最后把boolquerybuilder对象丢进searchsourcebuilder对象的query方法即可!!!
(8)New HighlightBuilder对象,这个对象有样式标签前后缀pretags、posttags、field字段名等方法。
//jest的dsl工具,帮忙生成查询语句
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//bool联合条件查询
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
//filter的term条件筛选
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("skuAttrValueList.valueId","47");
boolQueryBuilder.filter(termQueryBuilder);
//must的match关键字查询
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName","小米");
boolQueryBuilder.must(matchQueryBuilder);
//query查询
searchSourceBuilder.query(boolQueryBuilder);
//from起始条数
searchSourceBuilder.from(0);
//size查询数据条数
searchSourceBuilder.size(20);
//highlight高亮
searchSourceBuilder.highlight(null);
String dslStr = searchSourceBuilder.toString(); //根据用户搜索的内容和点击的筛选条件,生成最终查询语句!
System.err.print(dslStr);
打印最终生成的查询语句:
System.err.print(); //err是使打印的颜色变红!!!