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"
        }
      }
    ]
  }
}

 

posted @ 2022-07-12 15:55  山河永慕~  阅读(1212)  评论(0编辑  收藏  举报