elasticsearch 介绍、查询及使用(must、should)
创建索引
{ "mappings": { "properties": { "id": {"type":"keyword"}, "pname": {"type":"text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word","fields": {"keyword":{"type":"keyword"}}}, "title": {"type":"text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word","fields": {"keyword":{"type":"keyword"}}}, "describe": {"type":"text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word","fields": {"keyword":{"type":"keyword"}}}, "rich_text": {"type":"text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word","fields": {"keyword":{"type":"keyword"}}}, "update_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"} } } }
@Id @Field(index=true, store = true, type = FieldType.Keyword) private String id; /** * 更新时间 */ @JSONField(serialize = false) @Field(index = true, store = true, type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss") private Date update_time; /** * 标题 */ @Field(index = true, analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_smart", type = FieldType.Text) private String title; /** 名称*/ @Field(index = true, analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_smart", type = FieldType.Text) private String pname; /** * 摘要 */ @Field(index = true, analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_smart", type = FieldType.Text) private java.lang.String describe; /** * 文章正文 */ @JSONField(serialize = false) @Field(index = true, analyzer = "ik_max_word", store = true, searchAnalyzer = "ik_smart", type = FieldType.Text) private String rich_text;
查询介绍
must 返回的文档必须满足must子句的条件,并且参与计算分值
filter 返回的文档必须满足filter子句的条件,但是不会像must一样,参与计算分值
should 返回的文档可能满足should子句的条件.在一个bool查询中,如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回.
must_not 返回的文档必须不满足定义的条件
matchAllQuery匹配所有
termQuery精准匹配,大小写敏感且不支持
matchPhraseQuery对中文精确匹配
matchQuery("key", Obj) 单个匹配, field不支持通配符, 前缀具高级特性
multiMatchQuery("text", "field1", "field2"..); 匹配多个字段, field有通配符忒行
实现匹配模糊查询和等值查询
模糊查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.wildcardQuery("title", "*" + keyword + "*"));
等值查询 必须保存此字段有 “字段”.keyword 索引
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.matchQuery("title.keyword", keyword))
注意:当使用should查询时,如果包含了must或者filter查询,那么should的查询语句就不是或者的意思了,而是有或者没有都行的含义。
例如:在a=1且b=2的数据中,找出c=1或者d=2的数据
{ "query": { "bool": { "must": [{ "match": { "a": "1", "b": "2" } }], "should": [{ "match": { "c": "1" } }, { "match": { "d": "2" } } ] } } }
这样写的时候should是没有用的,这是新手可能犯的错误之一。 在编写查询条件的时候,不能用口头上的逻辑进行编写,而是要换成数学逻辑才能进行执行(数据库同理)。 如上例,数学逻辑应该是 (a==1&&b==2&&c==1)||(a==1&&b==2&&d==2)(java and c语言版),这样的结构去查询。
实现方式一:
QueryBuilder query = QueryBuilders.boolQuery() .should(QueryBuilders.boolQuery() .filter(QueryBuilders.termQuery("a", 1)) .filter(QueryBuilders.termQuery("b", 2)) .filter(QueryBuilders.termQuery("c", 1)) .should(QueryBuilders.boolQuery() .filter(QueryBuilders.termQuery("a", 1)) .filter(QueryBuilders.termQuery("b", 2)) .filter(QueryBuilders.termQuery("d", 2));
{ "query": { "bool": { "should": [{ "match": { "a": "1", "b": "2", "c": "1" } }], "should": [{ "match": { "a": "1", "b": "2", "d": "2" } }] } } }
实现方式二:
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.should(QueryBuilders.matchQuery("title", keyword)) boolQueryBuilder.should(QueryBuilders.matchQuery("pname", keyword)); //要求至少满足一个Should条件 boolQueryBuilder.minimumShouldMatch(1);
{ "bool" : { "must" : [ { "term" : { "site_id" : { "value" : 110, "boost" : 1.0 } } } ], "should" : [ { "match" : { "title" : { "query" : "咖啡", "operator" : "OR" } } }, { "match" : { "pname" : { "query" : "咖啡", "operator" : "OR" } } }, ], "minimum_should_match" : "1" } }
实现方式三:
String[] searchArray = new String[]{"title","pname"}; searchKeys.toArray(searchArray); boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword, searchArray).operator(Operator.AND));
{ "bool" : { "must" : [ { "term" : { "site_id" : { "value" : 110, "boost" : 1.0 } } }, { "multi_match" : { "query" : "咖啡", "fields" : [ "pname^1.0", "title^1.0" ], "operator" : "AND" } } ] } }
早年同窗始相知,三载瞬逝情却萌。年少不知愁滋味,犹读红豆生南国。别离方知相思苦,心田红豆根以生。