搜索请求的基本模块

  • query: 具体的搜索内容
  • size:返回文档的数量,默认10
  • from:偏移量:如果要看第二页的10个结果,ES需要计算出前20个结果->获取靠后的分页代价越来越大,默认0
  • _source:指定返回的字段,默认全部字段返回
  • sort:排序,默认的排序是按照文档的得分降序排
  • profile:分析
  • explain:计算得分过程

Search API

  • URI Search
    • 在 URL 上使用查询参数

image.png

  • Request Body Search
    • 使用 ElasticSearch 提供的,基于 JSON 格式的更加完备的 Query Domain Specific Language (DSL)

image.png

响应体解析

  1. {
  2. // 花费时间,毫秒
  3. "took": 4,
  4. // 是否超时
  5. "timed_out": false,
  6. // 涉及分片信息
  7. "_shards": {
  8. "total": 1,
  9. "successful": 1,
  10. "skipped": 0,
  11. "failed": 0
  12. },
  13. // 命中文档的信息组
  14. "hits": {
  15. // 命中数
  16. "total": {
  17. "value": 1,
  18. "relation": "eq"
  19. },
  20. // 命中文档中最大的匹配分数
  21. "max_score": 5.247024,
  22. // 命中文档详细信息
  23. "hits": [
  24. {
  25. // 文档索引
  26. "_index": "o2srh_o2pcm_platform_product_10_2",
  27. // 文档索引类型
  28. "_type": "_doc",
  29. // 文档id
  30. "_id": "hmbb_OW-1",
  31. // 此词搜索文档的匹配分数
  32. "_score": 5.247024,
  33. // 文档源字段
  34. "_source": {
  35. "platformProductCode": "hmbb",
  36. "title": "海绵宝宝",
  37. "stockFlag": 1
  38. }
  39. }
  40. ]
  41. }
  42. }

基于词项和基于全文的搜索

创建索引的Mapping结构

  1. PUT book
  2. {
  3. "mappings": {
  4. "dynamic": "false",
  5. "properties": {
  6. "nameText": {
  7. "type": "text",
  8. "analyzer": "standard"
  9. },
  10. "nameKeyWord": {
  11. "type": "keyword"
  12. },
  13. "country": {
  14. "type": "keyword"
  15. },
  16. "price": {
  17. "type": "float"
  18. }
  19. }
  20. }
  21. }

插入的数据

  1. [
  2. {
  3. "nameText":"ES in action ES",
  4. "nameKeyWord":"ES in action ES",
  5. "country":"China",
  6. "price":100
  7. },
  8. {
  9. "nameText":"ES in one action",
  10. "nameKeyWord":"ES in one action",
  11. "country":"Japan",
  12. "price":200
  13. },
  14. {
  15. "nameText":"ES in one two action",
  16. "nameKeyWord":"ES in one two action",
  17. "country":"America",
  18. "price":300
  19. },
  20. {
  21. "nameText":"What is ES",
  22. "nameKeyWord":"What is ES",
  23. "country":"China",
  24. "price":400
  25. },
  26. {
  27. "nameText":"one thing is good",
  28. "nameKeyWord":"one thing is good",
  29. "country":"America",
  30. "price":500
  31. }
  32. ]

nameText 字段被设置成 text 类型,会走分析流程,并且使用 设置的 standard分析器进行分析写入:

Term _id: 1 _id: 2 _id: 3 _id: 4 _id: 5
es 2 1 1 1
in 1 1 1
action 1 1 1
one 1 1 1
two 1
what 1
is 1 1
thing 1
good 1

基于全文的查询

特点:

  • 索引和搜索时都会进行分词,查询字符串先传递到一个合适的分词器,然后生成一个供查询的词项列表
  • 查询的时候,先会对输入的查询进行分词,然后每个词项逐个进行底层的查询,最终将结果进行合并。并为每个文档生成一个得分。

典型代表:

  • Match Query
  • Match Phrase Query
  • Match Phrase Prefix

基于 Term 的查询

Term 是分词语义的最小单位。

在 ES 中, Term 查询,对输入不做分词。会将输入作为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分。

可以利用 Constant Score 将查询转换成一个 Filtering,避免算分,并且利用缓存,提高性能。

典型代表组成:

  • Term Query
  • Range Query
  • Prifix Qery

ES 的两种搜索上下文

  • query context:
    • 关注点是的是匹配度有多高,并计算出匹配分数,关注点是match
    • 查询:计算文档得分
    • 结果不会缓存
    • 走的是倒排索引
    • 应用场景:全文检索以及任何需要相关性的场景
  • filter context:
    • 关注点是匹配与否,并不需要计算分数,关注点是 included or not
    • 只筛选出符合的文档,不算得分
    • 缓存文档 ——>大范围筛选数据
    • 走的是 Bitsets
    • 应用场景:完全精确匹配,范围检索

性能比较

  • query context除了检索外,还需要计算相关度
  • filter 有缓存

filter context 怎么缓存

  • ES 会创建一个文档匹配过滤器的位集 bitset,文档匹配就是1,否则为0,随后用相同的过滤器查询就会重用这部分缓存。
  • 当创建/更新文档时,bitset也会更新

Lucene金科玉律:尽量用 filter context,除非必须使用 query context(当且仅当需要计算分的时候)

bool 复合查询

是一个或者多个查询子句的组合。组合查询。
bool:

  • query context:
    • must:必须匹配。贡献算分
    • should:选择性匹配。贡献算分。
  • filter context:
    • must not:查询字句,必须不能匹配
    • filter:必须匹配,但不贡献算分

聚合(Aggregation)

ES 对数据进行统计分析的功能,

经典组成:

  • Bucket Aggregation
    • 分组,一组满足条件的文档
  • Metric Aggregation
    • 一系列的统计方法(最大值、最小值、平均值)

image.png