11 搜索之url搜索和搜索类型

1 准备数据

  1. 构建个文章的索引
PUT article
{
  "mappings": {
    "properties": {
      "id":{
        "type": "long"
      },
      "title":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "category":{
        "type": "keyword"
      },
      "author":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "content":{
        "type": "text",
         "analyzer": "ik_max_word"
      },
      "createAt":{
        "type": "date",
        "format": ["yyyy-MM-dd hh:mm:ss"]
      }
    }
  }
}
  1. 先插入一条数据,后面根据测试的需要进行增加
PUT article/_doc/1
{
  "id":1,
  "title":"elasticsearch技术解析与实战",
  "category":"计算机技术",
  "author":"朱林",
  "content":"elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
  "createAt":"2016-12-12 10:00:00"
}
  1. 根据id查询一下数据

请求

GET article/_doc/1

响应

{
  "_index" : "article",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "id" : 1,
    "title" : "elasticsearch技术解析与实战",
    "category" : "计算机技术",
    "author" : "朱林",
    "content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
    "createAt" : "2016-12-12 10:00:00"
  }
}

2 url搜索

请求格式:
GET http"//localhost:9200/索引库名字/_search?参数,多个参数使用&符号分开。

参数一:q:查询字符串

可以指定查询字段,如果不指定,es 会查询所有字段

例如:

# 查询id为1的文档
GET article/_search?q=id:1
# 查询author为朱林的
GET article/_search?q=author:朱林
# 查询author包含朱
GET article/_search?q=author:朱
# 查询类目为计算机技术
GET article/_search?q=category:计算机技术
GET article/_search?q=category:计算机

除了最后一个查不出刚刚数据:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

很简单的类目字段为keyword,不会被分词,所以类目查询计算机是会被搜索出来的,而作者字段类型是text,会被分词,所以查询朱还是林又或者是朱林都能被索引出来。

之前讲过的source过滤,超市时间也是可以的

# 只返回title和author字段,超时时间为5m
GET article/_search?q=category:计算机技术&_source_includes=title,author&timeout=5m
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "article",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "author" : "朱林",
          "title" : "elasticsearch技术解析与实战"
        }
      }
    ]
  }
}

当然也可以不指定字段,这就是查询所有字段

GET article/_search?q=朱林

新增一条数据

PUT article/_doc/2
{
  "id":2,
  "title":"朱林传记",
  "category":"传记",
  "author":"王小虎",
  "content":"资深开发人员,有16年开发经验,11年安全产品开发经验,对安全技术、日志分析有较深的研究。于2013年创立南京赛克蓝德网络科技有限公司,公司专注于安全产品的开发,目前主要开发的产品是赛克蓝德日志分析软件。",
  "createAt":"2016-12-12 10:00:00"
}

执行上面的查询,就会把两条数据都搜索出来

{
  "took" : 632,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.5442266,
    "hits" : [
      {
        "_index" : "article",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.5442266,
        "_source" : {
          "id" : 2,
          "title" : "朱林传记",
          "category" : "传记",
          "author" : "王小虎",
          "content" : "资深开发人员,有16年开发经验,11年安全产品开发经验,对安全技术、日志分析有较深的研究。于2013年创立南京赛克蓝德网络科技有限公司,公司专注于安全产品的开发,目前主要开发的产品是赛克蓝德日志分析软件。",
          "createAt" : "2016-12-12 10:00:00"
        }
      },
      {
        "_index" : "article",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.3862942,
        "_source" : {
          "id" : 1,
          "title" : "elasticsearch技术解析与实战",
          "category" : "计算机技术",
          "author" : "朱林",
          "content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
          "createAt" : "2016-12-12 10:00:00"
        }
      }
    ]
  }
}

执行下面的查询就只会查出一条数据:author是朱林的那条

GET article/_search?q=author:朱林
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3862942,
    "hits" : [
      {
        "_index" : "article",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.3862942,
        "_source" : {
          "id" : 1,
          "title" : "elasticsearch技术解析与实战",
          "category" : "计算机技术",
          "author" : "朱林",
          "content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
          "createAt" : "2016-12-12 10:00:00"
        }
      }
    ]
  }
}

参数2:df

定义查询时,默认的查询字段

GET article/_search?q=朱林&df=author

这里就指定了默认查询字段是author,刚刚上面没有指定,会查询出两条数据,这里指定了就只会去查询author字段,只会查询:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3862942,
    "hits" : [
      {
        "_index" : "article",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.3862942,
        "_source" : {
          "id" : 1,
          "title" : "elasticsearch技术解析与实战",
          "category" : "计算机技术",
          "author" : "朱林",
          "content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
          "createAt" : "2016-12-12 10:00:00"
        }
      }
    ]
  }
}

参数3 timeout

搜索超时,将搜索请求限制在指定的时间值内执行,并使用在到期时累积的点击数进行保释。默认为无超时。

参数 sort

排序执行。可以是fieldName或 fieldName:asc / fieldName:desc。fieldName可以是文档中的实际字段,也可以是特殊_score名称,表示基于分数的排序。可以有几个sort参数(顺序很重要)。

# 根据id降序
GET article/_search?sort=id:desc

# 也可以是_score这种特殊字段
GET article/_search?sort=_score:desc

设置了排序字段就不会返回评分信息了(除了按照_score排序之外)
在这里插入图片描述

参数 track_scores

通过这个参数就可以,在使用其他排序字段的时候,依旧返回得分情况,默认是false

GET article/_search?sort=id:desc&track_scores=true

在这里插入图片描述

参数 _source

设置为false禁用_source字段检索。您还可以使用_source_include&检索部分文档_source_exclude,默认是true
这个前面已经介绍过:https://blog.csdn.net/wyaoyao93/article/details/110325063

GET article/_search?q=category:计算机技术&_source_includes=title,author

参数 track_total_hits

设置为false禁用跟踪与查询匹配的匹配总数。默认为true。
设置为false,不会返回匹配的总条数,total字段返回值为-1
简单来说就是返回查询到的总数

GET article/_search?track_total_hits=false

参数 search_type

要执行的搜索操作的类型。可以是 dfs_query_then_fetch或query_then_fetch。默认为query_then_fetch。有关可以执行的不同搜索类型的更多详细信息,请参阅 搜索类型。

参数 explain

每个返回结果中,将包含评分机制的解释,默认是false

GET article/_search?explain=true

参数 terminate_after: 每个分片中查询的最大条数

每个分片中查询的最大条数,如果设置了,返回结果中会有一个terminated_early字段

GET article/_search?terminate_after=1
{
  "took" : 0,
  "timed_out" : false,
  "terminated_early" : true,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "article",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "id" : 1,
          "title" : "elasticsearch技术解析与实战",
          "category" : "计算机技术",
          "author" : "朱林",
          "content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
          "createAt" : "2016-12-12 10:00:00"
        }
      }
    ]
  }
}

这里只查出一条,因为我们就一个分片,每个分片最大返回1条,所以只返回了一条数据

分页: from和size

from:索引匹配结果的偏移值,默认是0
size:默认是10,搜索结果返回的条数

# 查询第一页,每页1GET article/_search?from=0&size=1
# 查询第二页,每页1GET article/_search?from=1&size=1

3 Search Type(搜索类型)

3.1 分布式搜索背景介绍

ES天生就是为分布式而生,但分布式有分布式的缺点。比如要搜索某个单词,但是数据却分别在5个分片(Shard)上面,这5个分片可能在5台主机上面。因为全文搜索天生就要排序(按照匹配度进行排名),但数据却在5个分片上,如何得到最后正确的排序呢?ES是这样做的,大概分两步。

  1. ES客户端会将这个搜索词同时向5个分片发起搜索请求,这叫Scatter,
  2. 这5个分片基于本Shard独立完成搜索,然后将符合条件的结果全部返回,这一步叫Gather。
    客户端将返回的结果进行重新排序和排名,最后返回给用户。也就是说,ES的一次搜索,是一次scatter/gather过程(这个跟mapreduce也很类似).

3.2 两个问题

数量问题

比如,用户需要搜索”双黄连”,要求返回最符合条件的前10条。但在5个分片中,可能都存储着双黄连相关的数据。所以ES会向这5个分片都发出查询请求,并且要求每个分片都返回符合条件的10条记录。当ES得到返回的结果后,进行整体排序,然后取最符合条件的前10条返给用户。这种情况,ES最多会收到10*5=50条记录

排名问题

上面搜索,每个分片计算分值都是基于自己的分片数据进行计算的。计算分值使用的词频率和其他信息都是基于自己的分片进行的,而ES进行整体排名是基于每个分片计算后的分值进行排序的,这就可能会导致排名不准确的问题。如果我们想更精确的控制排序,应该先将计算排序和排名相关的信息(词频率等)从5个分片收集上来,进行统一计算,然后使用整体的词频率去每个分片进行查询

3.3 Search Type

为了解决上面的问题,es提出了Search Type的概念,交给用户来选择不同的搜索类型

query and fetch

向索引的所有分片(shard)都发出查询请求,各分片返回的时候把元素文档(document)和计算后的排名信息一起返回。这种搜索方式是最快的。因为相比下面的几种搜索方式,这种查询方法只需要去shard查询一次。但是各个shard返回的结果的数量之和可能是用户要求的size的n倍。

query then fetch(默认的搜索方式)

这种搜索方式,大概分两个步骤,第一步,先向所有的shard发出请求,各分片只返回排序和排名相关的信息(注意,不包括文档document),然后按照各分片返回的分数进行重新排序和排名,取前size个文档。然后进行第二步,去相关的shard取document。

DFS query and fetch

这种方式比query and fetch多了一个初始化散发(initial scatter)步骤,有这一步,据说可以更精确控制搜索打分和排名。DFS query and fetch 返回结果的数量是 分片数*size

DFS query then fetch

比query then fetch多了一个初始化散发(initial scatter)步骤。这种方式返回的document与用户要求的size是相等的。

总结一下,从性能考虑QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。从搜索的准确度来说,DFS要比非DFS的准确度更高

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值