ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

elasticsearch 介绍、查询及使用(must、should)

2022-07-12 16:02:37  阅读:189  来源: 互联网

标签:keyword analyzer should ik elasticsearch type QueryBuilders must


创建索引

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

 

标签:keyword,analyzer,should,ik,elasticsearch,type,QueryBuilders,must
来源: https://www.cnblogs.com/shanheyongmu/p/16470371.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有