Elasticsearch查询

苏颙
• 阅读 187
elasticsearch版本7.3.0
主要记录语句格式,不会囊括所有查询方式

Validate api:

GET /index/_validate/query?explain
用于特别复杂庞大的搜索,如写了上百行的搜索语句,这个时候可以先用validate api去验证一下,搜索是否合法

查询返回结果:

took:耗费了几毫秒
timed_out:是否超时,默认无timeout
_shards:数据拆成了n个分片,所以对于搜索请求,会打到所有的primary shard(或者是它的某个replica shard也可以)
hits.total:查询结果的数量,共有n个document
hits.max_score:本次搜索的所有结果中,最大的相关度分数
hits.hits:包含了匹配搜索的document的详细数据,默认查询前10条数据,完整数据的_score降序排序
元数据:
_index:代表一个文档放在哪个索引中,索引名称必须是小写的,不能用下划线开头,不能包含逗号
_type:代表文档属于index中的哪个类别
_id:文档的唯一标识,与索引和类型一起,定位到一个文档,新增数据时可以指定,也可以默认es创建,数据导入es时可以指定
_version:创建一个document的时候,它的_version内部版本号就是1;之后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1;即使删除,也会对这条数据的版本号加1
_source: 里面指定要返回的字段,默认返回所有

查询结果的排序:

搜索依靠倒排索引,排序依靠正排索引,即doc value。
doc values是被保存在磁盘上的,此时如果内存足够,os会自动将其缓存在内存中;如果内存不足够,操作系统会将其写入磁盘上。
定制排序规则,只需要在查询语句加入sort即可,数组,优先级从上到下:

"sort": [
    {
      "fieldname": {
        "order": "asc"
      }
    }
  ]

Multi-index搜索:

/_search:所有索引下的所有数据都搜索出来
/index1/_search:指定一个index,搜索其下所有数据
/index1,index2/_search:同时搜索两个index下的数据
/*1,*2/_search:按照通配符去匹配多个索引
_all,可以代表搜索所有index

query string search:

GET /index/_search?q=field:fieldvalue&sort=field:desc
GET /index/_search?q=+fieldname:fieldvalue   +:必须包含;-:必须不包含

query DSL:

GET /index/_search
{
  "query": {
    "match": {
      "fieldname": "fieldvalue"
    }
  },
  "_source": [
    "fieldname1",
    "fieldname2"
  ],
  "sort": [
    {
      "fieldname": "desc"
    }
  ]
}

query filter:

每个query查询中的子查询都会计算一个document针对它的相关度分数,然后bool综合所有分数,合并为一个分数,但是filter不计算分数

  • filter:按照搜索条件过滤出需要的数据,不计算任何相关度分数,对相关度没有任何影响,性能好,同时内部会自动缓存常使用filter的数据。
  • query:会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序,性能差,无缓存,但可以按照分数排序。
GET /index/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "fieldname": "fieldvalue"
        }
      },
      "filter": {
        "range": {
          "field": {
            "gt": 0,
            "lt": 1
          }
        }
      }
    }
  },
  "size": 1
}

phrase search(短语搜索):

完全匹配条件

GET /index/_search
{
  "query": {
    "match_phrase": {
      "fieldname": "fieldvalue"
    }
  }
}

highlight search(高亮搜索结果):

GET /index/_search
{
  "query": {
    "match": {
      "fieldname": "fieldvalue"
    }
  },
  "highlight": {
    "fields": {
      "fieldname": {}
    }
  }
}

multi match:

多字段匹配

GET /index/_search
{
  "query": {
    "multi_match": {
      "query": "fieldvalue",
      "fields": [
        "fieldname1",
        "fieldname2"
      ]
    }
  }
}

聚合搜索:

GET /index/_search
{
  "size": 0,
  "aggs": {
    "agg_name": {
      "terms": {
        "field": "fieldname"
      }
    }
  }
}

聚合搜索之后求平均值,并且按照平均数降序排序

GET /index/_search
{
  "size": 0,
  "aggs": {
    "agg_name1": {
      "terms": {
        "field": "fieldname",
        "order": {
          "agg_name2": "desc"
        }
      },
      "aggs": {
        "agg_name2": {
          "avg": {
            "field": "fieldname"
          }
        }
      }
    }
  }
}

按照指定区间分组,并计算平均数:

GET /index/_search
{
  "size": 0,
  "aggs": {
    "agg_name1": {
      "range": {
        "field": "fieldname(age)",
        "ranges": [
          {
            "from": 0,
            "to": 20
          },
          {
            "from": 20,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "agg_name2": {
          "terms": {
            "field": "fieldname"
          },
          "aggs": {
            "agg_name3": {
              "avg": {
                "field": "fieldname"
              }
            }
          }
        }
      }
    }
  }
}

聚合去重:

GET /index/_search
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "fieldname": "fieldvalue"
          }
        },
        {
          "range": {
            "fieldname": {
              "gte": fieldvalue1,
              "lte": fieldvalue2,
              "format": "epoch_millis"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "agg_name": {
      "cardinality": {
        "field": "fieldname"
      }
    }
  }
}

批量查询:

批量查询可以减少网络连接次数,性能优化会非常明显

GET /_mget
{
  "docs": [
    {
      "_index": "indexname1",
      "_id": "id1"
    },
    {
      "_index": "indexname2",
      "_id": "id2"
    }
  ]
}

同一索引下:

GET /index/_mget
{
   "ids": ["id1", "id2"]
}

timeout机制:

指定timeout,如:添加参数?timeout=1m
timeout机制原理指限定在一定时间内,将部分获取到的数据直接返回,避免查询耗时过长

分页查询:

from,size分页查询:

GET /index/_search
{
  "from": 0,
  "size": 5
}

数据量大的情况不建议,会让所有节点全返回前5条,然后协调节点合并再去5条。
scroll api

  • 滚动搜索,先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来。
  • 会在第一次搜索的时候,保存一个视图快照,之后只会基于该视图快照提供数据搜索,期间用户不会看到正在修改的数据
  • 采用基于_doc进行排序的方式,性能较高
  • 每次发送scroll请求,我们还需要指定一个scroll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了
  • 第一次之后的每次搜索都要带上返回的scroll id

第一次查询:

GET /index/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "sort": [
    "_doc"
  ],
  "size": 1
}

第二次查询:

GET /_search/scroll
{
  "scroll": "1m",
  "scroll_id": "J5VGh...lbkZldG"
}
get请求和post请求都支持

-----------------------------------------------------

bouncing results问题:
两个document排序,field值相同;不同的shard上,可能排序不同;每次请求轮询打到不同的replica shard上;
每次页面上看到的搜索结果的排序都不一样。这就是bouncing result,也就是跳跃的结果。
解决方案:将preference设置为一个字符串如用户id之类,也可以设置routing值
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Feign请求响应结果被截取com.fasterxml.jackson.core.io.JsonEOFException
在生产环境使用feign调用外部接口时,偶尔会出现下面错误2020101511:00:18,535ERRORcom.shein.abc.rmp.controller.RecExplainConfigControllerrec_explain_query.failffeign.codec.DecodeExc
Easter79 Easter79
3年前
SQLAlchemy和Flask
假设page\_index1,page\_size10;所有分页查询不可以再跟first(),all()等1.用offset()设置索引偏移量,limit()限制取出filter语句后面可以跟order_by语句db.session.query(User.name).filter(User.email.li
Stella981 Stella981
3年前
SQLAlchemy和Flask
假设page\_index1,page\_size10;所有分页查询不可以再跟first(),all()等1.用offset()设置索引偏移量,limit()限制取出filter语句后面可以跟order_by语句db.session.query(User.name).filter(User.email.li
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
苏颙
苏颙
Lv1
远书归梦两悠悠,只有空床敌素秋。
文章
4
粉丝
0
获赞
0