Elasticsearch-入门到精通-3 六种搜索 restful api


搜索是ES中非常重要的功能,搜索的api是 _search

根据restful风格,搜索(查询)是幂等操作,http方法是GET请求。

基本语法:

GET /index/type/_search

共有六种搜索方式,都是基于以上语法,本文只写基本语法,具体的示例网上资料挺丰富的,不再重复咯。文末会贴参考链接

1、字符串(query string)搜索

我们像传递URL参数一样去传递查询语句:
语法:

GET /index/type/_search?q=field_name:queryCondition
GET /索引/类型/_search?q=字段名:字段值

注意 ?q 是语法中的一部分哦。指的是拼接参数。
适用于临时的在命令行使用一些工具,比如curl,快速的发出请求,来检索想要的信息;但是如果查询请求很复杂,是很难去构建的,在生产环境中,几乎很少使用query string search

思考:

多个条件怎么拼接该参数?

示例:

GET /megacorp/employee/_search?q=last_name:Smith

2、query DSL

DSL:Domain Specified Language,特定领域的语言
http request body:请求体,可以用json的格式来构建查询语法,比较方便,可以构建各种复杂的语法,比query string search肯定强大多了

(1)查询所有的商品

GET /ecommerce/product/_search
{
  "query": { "match_all": {} }
}

(2)条件查询,排序

查询名称包含yagao的商品,同时按照价格降序排序

GET /ecommerce/product/_search
{
    "query" : {
        "match" : {
            "name" : "yagao"
        }
    },
    "sort": [
        { "price": "desc" }
    ]
}

(3)分页查询商品

总共3条商品,假设每页就显示1条商品,现在显示第2页,所以就查出来第2个商品

GET /ecommerce/product/_search
{
  "query": { "match_all": {} },
  "from": 1,
  "size": 1
}

(4)指定搜索结果字段

指定要查询出来商品的名称和价格就可以

GET /ecommerce/product/_search
{
  "query": { "match_all": {} },
  "_source": ["name", "price"]
}

query DSL 更加适合生产环境的使用,可以构建复杂的查询

3、query filter/ filter DSL

示例

搜索商品名称包含yagao,而且售价大于25元的商品

GET /ecommerce/product/_search
{
    "query" : {
        "bool" : {
            "must" : {
                "match" : {
                    "name" : "yagao" 
                }
            },
            "filter" : {
                "range" : {
                    "price" : { "gt" : 25 } 
                }
            }
        }
    }
}

这个例子,看上去就是queryDSL的复杂版,为啥叫query filter?
本人的理解:
其实就是requestbody中,的关键字不一样。
queryDSL,关键字比较简单,query、sort、from、size,_search
filterDSL,看上去就比较复杂了点,像本例中的filter、bool都是filter的关键字。

也有比较专业解释二者区别的:

query DSL 和query filter的区别

query DSL
在查询上下文中,查询会回答这个问题——“这个文档匹不匹配这个查询,它的相关度高么?”

如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂的,因此也需要一定的时间。

查询上下文 是在 使用query进行查询时的执行环境,比如使用search的时候。

一些query的场景:

与full text search的匹配度最高
包含run单词,如果包含这些单词:runs、running、jog、sprint,也被视为包含run单词
包含quick、brown、fox。这些词越接近,这份文档的相关性就越高

filter DSL
在过滤器上下文中,查询会回答这个问题——“这个文档匹不匹配?”

答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。

过滤上下文 是在使用filter参数时候的执行环境,比如在bool查询中使用Must_not或者filter

另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提高很多性能。

一些过滤的情况:

创建日期是否在2013-2014年间?
status字段是否为published?
lat_lon字段是否在某个坐标的10公里范围内?

关于二者的区别联系不多介绍,可以查看参考网址(以上文字也是摘抄自该文章)。
参考网址:https://www.cnblogs.com/bainianminguo/articles/10396956.html

4、full-text search(全文检索)

全文检索是关系型数据库比较难处理的,但ES可以轻松的解决,这得益于它的基本原理:为每一个字段都创建倒排索引,关于这部分理论内容,参考文章:Elasticsearch-入门到精通-1 学习路线及概念

本例中,假设有这样几条数据:

idnamedescpriceproducertags
1gaolujie yagaogaoxiao meibai30gaolujie producermeibai,fangzhu
2jiajieshi yagaoyouxiao fangzhu25jiajieshi producerfangzhu
3zhonghua yagaocaoben zhiwu40zhonghua producerqingxin
4special yagaospecial meibai50special yagao producermeibai

有这样的一个查询,查询producer字段中,包含yagao producer的数据:

GET /ecommerce/product/_search
{
    "query" : {
        "match" : {
            "producer" : "yagao producer"
        }
    }
}

咦,怎么看上去跟第二部分的query DSL的查询很像,是的没错,不过,这里主要想表达的是ES的全文检索的原理。
数据添加如ES的时候,ES会为每一个字段建立倒排索引,producer字段也是一样,如下:

termposting list
special4
yagao4
producer1,2,3,4
gaolujie1
zhognhua3
jiajieshi2

查询条件中的yagao producer,会被分词为yagao和 producer
那么,查倒排索引,yagao会匹配到4,producer会匹配到1234文档,因此文档4的匹配度最高,也就是相关度最高,我们看查询结果:
其中id为4的_score属性,值是最高的,也就是相关度最高。

不过还有一个小疑问啊:
为什么1/3的相关度为0.25811607,而2的相关度为0.1805489?

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4,
    "max_score": 0.70293105,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_score": 0.70293105,
        "_source": {
          "name": "special yagao",
          "desc": "special meibai",
          "price": 50,
          "producer": "special yagao producer",
          "tags": [
            "meibai"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": 0.25811607,
        "_source": {
          "name": "gaolujie yagao",
          "desc": "gaoxiao meibai",
          "price": 30,
          "producer": "gaolujie producer",
          "tags": [
            "meibai",
            "fangzhu"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "3",
        "_score": 0.25811607,
        "_source": {
          "name": "zhonghua yagao",
          "desc": "caoben zhiwu",
          "price": 40,
          "producer": "zhonghua producer",
          "tags": [
            "qingxin"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": 0.1805489,
        "_source": {
          "name": "jiajieshi yagao",
          "desc": "youxiao fangzhu",
          "price": 25,
          "producer": "jiajieshi producer",
          "tags": [
            "fangzhu"
          ]
        }
      }
    ]
  }
}

5、phrase search(短语搜索)

跟全文检索相对应,相反,全文检索会将输入的搜索串拆解开来,去倒排索引里面去一一匹配,只要能匹配上任意一个拆解后的单词,就可以作为结果返回
phrase search,要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的,才可以算匹配,才能作为结果返回

以上文中的数据做例子,看一个例子,注意与全文检索的区别是match_phrase 关键字:

GET /ecommerce/product/_search
{
    "query" : {
        "match_phrase" : {
            "producer" : "yagao producer"
        }
    }
}

查询结果为:

{
  "took": 11,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.70293105,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_score": 0.70293105,
        "_source": {
          "name": "special yagao",
          "desc": "special meibai",
          "price": 50,
          "producer": "special yagao producer",
          "tags": [
            "meibai"
          ]
        }
      }
    ]
  }
}

6、highlight search(高亮搜索结果)

关键字:highlight

GET /ecommerce/product/_search
{
    "query" : {
        "match" : {
            "producer" : "producer"
        }
    },
    "highlight": {
        "fields" : {
            "producer" : {}
        }
    }
}

一些示例,包括返回值的说明,网上有不少示例,本文就不做演示了:
参考网址:
https://www.cnblogs.com/bigben0123/articles/11075949.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值