TypechoJoeTheme

顿搜

统计

05. 全文检索查询——ElasticSearch搜索专栏

2022-06-14
/
0 评论
/
241 阅读
/
正在检测是否收录...
06/14

不同于结构化查询,全文搜索首先对查询词进行分析,然后根据查询词的分词结果构建查询。

这里所说的全文指的是文本类型数据(text类型),默认的数据形式是人类的自然语言

结构化搜索关注的是数据是否匹配,全文搜索关注的是匹配的程度;

结构化搜索一般用于精确匹配,而全文搜索用于部分匹配。

一、Match查询

match查询是全文搜索的主要代表。

对于最基本的math搜索来说,只要分词中的一个或者多个在文档中存在即可。

例如搜索“金都酒店”,查询词先被分词器切分为“金都”、“酒店”

因此,只要文档中包含这2个词中的任何一个,都会被搜索到。

1.1 DSL方式

GET /hotel/_search
{
  "_source": ["title"],      //只返回title字段
  "query": {
   "match": {                //匹配title字段为“金都酒店”的文档
      "title": "金都酒店"
    }
  }
}

match搜索可以设置operator参数,该参数决定文档按照分词后的词集合进行“与”还是“或”匹配。

在默认情况下,该参数的值为“或”关系,即operator的值为or

下面的请求示例设置查询词之间的匹配结果为“与”关系:

GET /hotel/_search
{
  "_source": ["title"],  
  "query": {
    "match": {
      "title":{
        "query": "金都",
        "operator":"and"      //查询词之间的匹配结果为“与”关系
      }
    }
  }
}  

这时可以采用minimum_should_match参数,该参数叫作最小匹配参数,

其值为一个数值,意义为可以匹配上的词的个数。

GET /hotel/_search
{
  "_source": ["title"],  
  "query": {
    "match": {
      "title": {                          //match搜索条件
        "query": "金都",
        "operator": "or",
        "minimum_should_match": "80%"     //设置最小匹配度为80%
      }
    }
  }
}

1.2 Java 客户端方式

在Java客户端上可以使用QueryBuilders.matchQuery()方法构建match请求,

分别给该方法传入字段名称和查询值即可进行match查询。

public void matchSearch() {
    SearchRequest searchRequest = new SearchRequest();  //新建搜索请求
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.matchQuery("title", "金都")
        .operator(Operator.AND));   //新建match查询,并设置operator值为and
    searchRequest.source(searchSourceBuilder);         //设置查询
   printResult(searchRequest);                         //打印结果
}

二、multi_match查询

有时用户需要在多个字段中查询关键词,除了使用布尔查询封装多个match查询之外,可替代的方案是使用multi_match。

可以在multi_match的query子句中组织数据匹配规则,并在fields子句中指定需要搜索的字段列表。

2.1 DSL方式

GET /hotel/_search
{
  "_source": ["title","amenities"],  
  "query": {
    "multi_match": {
      "query": "假日",            //匹配关键字为“假日”
      "fields": [                 //设置匹配的字段为title和amenities
        "title",
        "amenities"
      ]
    }
  }
}  

他们之间是或的关系

2.2 Java 客户端方式

public void multiMatchSearch() {
    SearchRequest searchRequest = new SearchRequest();  //新建搜索请求
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //新建multi_match查询,从"title"和"amenities"字段查询"假日"
    searchSourceBuilder.query(QueryBuilders.multiMatchQuery("假日", "title", "amenities"));
    searchRequest.source(searchSourceBuilder);    //设置查询
   printResult(searchRequest);                    //打印结果
}

三、match_phrase查询

match_phrase用于匹配短语,与match查询不同的是,match_phrase用于搜索确切的短语或邻近的词语。

假设在酒店标题中搜索“文雅酒店”,

希望酒店标题中的“文雅”与“酒店”紧邻并且“文雅”在“酒店”前面,则使用match_phrase查询

3.1 DSL方式

GET /hotel/_search
{
  "query": {
    "match_phrase": {
      "title": "文雅酒店"
    }
  }
}  

可以设置match_phrase查询的slop参数,它用来调节匹配词之间的距离阈值。

默认slop = 0, 也就是必需紧挨着

GET /hotel/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "文雅酒店",
        "slop": 2              //将“文雅”和“酒店”之间的最大匹配距离设置为2
      }
    }
  }
}  

3.2 Java 客户端方式

在Java客户端上可以使用QueryBuilders.matchPhraseQuery()方法构建match_phrase请求,

分别给该方法传入查询字段和值即可进行match_phrase查询。

public void matchPhraseSearch() {
    SearchRequest searchRequest = new SearchRequest(); //新建搜索请求
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    //新建match_phrase查询,并设置slop值为2
    QueryBuilder matchPhraseQueryBuilder=QueryBuilders.matchPhraseQuery("title","文雅酒店").slop(2);
    searchSourceBuilder.query(matchPhraseQueryBuilder);
    searchRequest.source(searchSourceBuilder);  //设置查询
   printResult(searchRequest);                  //打印结果
}
朗读
赞 · 0
版权属于:

顿搜

本文链接:

https://dun.so/archives/2872/(转载时请注明本文出处及文章链接)