Elasticsearch原理概念及各種查詢語(yǔ)句

es的官方中文文檔
https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
概念
es是基于Lucene,純java語(yǔ)言編寫(xiě)的分布式再芋,可擴(kuò)展,近實(shí)時(shí)性的高性能搜索引擎和數(shù)據(jù)分析引擎

es基礎(chǔ)構(gòu)成

  • doc
    es中數(shù)據(jù)存儲(chǔ)的最小單元,對(duì)應(yīng)數(shù)據(jù)庫(kù)的一行數(shù)據(jù)
  • Index
    有具有相同字段的文檔列表組成,對(duì)應(yīng)數(shù)據(jù)庫(kù)的一個(gè)表,一個(gè)索引由一個(gè)或者多個(gè)分片組成
  • type
    文檔類型挣棕,這個(gè)我們可以不用記辛孵,es后面的版本要把type去掉。之前的版本中洲守,索引和文檔中間還有個(gè)類型的概念,每個(gè)索引下可以建立多個(gè)類型沾凄,文檔存儲(chǔ)時(shí)需要指定index和type梗醇。從6.0.0開(kāi)始單個(gè)索引中只能有一個(gè)類型,7.0.0以后將將不建議使用搭独,8.0.0 以后完全不支持婴削。在7.0開(kāi)始,一個(gè)索引只能建一個(gè)Type為_(kāi)doc牙肝。
  • shards
    分片唉俗。當(dāng)索引數(shù)據(jù)太大時(shí),受限于單個(gè)節(jié)點(diǎn)的磁盤(pán)配椭,內(nèi)存虫溜,處理能力等資源,需要將索引的數(shù)據(jù)水平拆分股缸,拆分后形成的每一個(gè)分片回落到不一樣的服務(wù)節(jié)點(diǎn)上衡楞,這樣顯著提升了es的性能,索引創(chuàng)建時(shí)需要指定分片敦姻,一旦分片被指定就無(wú)法更改
  • replicas
    副本瘾境。是主分片的備份分片,副本主要是用于主分片的數(shù)據(jù)備份镰惦,同時(shí)也對(duì)外提供數(shù)據(jù)查詢服務(wù)迷守。副本分片提升了es的高可用性
分片shard和es集群的高可用高性能

分片的概念和kafka的分區(qū)很像,既有副本又各自擁有不同的數(shù)據(jù)并且分散在不同的節(jié)點(diǎn)旺入,index就是這些分片的topic兑凿。

一個(gè)索引中的數(shù)據(jù)保存通過(guò)hash取余決定保存在哪分片中凯力,相當(dāng)于水平分表也類似于kafka的分區(qū),分片有主分片和副本分片礼华,一個(gè)主分片可以設(shè)置多個(gè)副本分片咐鹤,在es集群中每個(gè)主分片存儲(chǔ)了es的部分?jǐn)?shù)據(jù),副本分片主要是用于備份主分片的數(shù)據(jù)圣絮,主分片分布在es的各個(gè)節(jié)點(diǎn)上祈惶,而各個(gè)主分片的副本分片也會(huì)分布到和主分片不同的節(jié)點(diǎn)上,當(dāng)集群中某個(gè)節(jié)點(diǎn)宕機(jī)時(shí)晨雳,分布在其他節(jié)點(diǎn)的副本分片就會(huì)頂替原來(lái)的主分片行瑞,這個(gè)體現(xiàn)了es的高可用性。

由于分片分散在各個(gè)不同的節(jié)點(diǎn)上餐禁,每個(gè)節(jié)點(diǎn)都有能力處理任意請(qǐng)求, 每個(gè)節(jié)點(diǎn)都知道集群中任一文檔位置突照,所以可以直接將請(qǐng)求轉(zhuǎn)發(fā)到需要的節(jié)點(diǎn)上帮非,所以其請(qǐng)求壓力和數(shù)據(jù)分析壓力也會(huì)分散到集群的各個(gè)節(jié)點(diǎn)上,實(shí)現(xiàn)了es的高性能讹蘑。我們最好通過(guò)輪詢的方式訪問(wèn)集群的節(jié)點(diǎn)

分片的原理就和數(shù)據(jù)庫(kù)的水平分表和kafka的分區(qū)是一個(gè)道理的末盔,既能保證高新南

下圖的流程展示es集群的高可用

圖一:es集群中有三個(gè)節(jié)點(diǎn),三個(gè)主分片座慰,三個(gè)副本分片陨舱,也就是每個(gè)分片擁有一個(gè)副本分片

圖一

圖二:主節(jié)點(diǎn)宕機(jī),node2通過(guò)選舉稱為新主節(jié)點(diǎn)

圖二

圖三:掛掉的node1的副本分片存儲(chǔ)在node3上,集群將副本分片P0調(diào)整為主分片版仔,這樣node1的數(shù)據(jù)就恢復(fù)回來(lái)了

圖三

圖四:es集群將為創(chuàng)建P0的副本分片游盲,和重新創(chuàng)建和node1一起掛掉的R1副本分片,并讓它們保存在和自己主分片不一樣的節(jié)點(diǎn)上蛮粮,也就是P0副本分片保存在node2上,R1副本分片保存在node3上益缎,下次就算是在宕機(jī),其中的一個(gè)節(jié)點(diǎn)存在有其他備份分片然想,保證了數(shù)據(jù)的不丟失莺奔,這就是es的高可用性

圖四

數(shù)據(jù)被存儲(chǔ)到哪個(gè)分片是由公式?jīng)Q定的:
shard = hash(routing) % number_of_primary_shards
routing 是一個(gè)可變值,默認(rèn)是文檔的 _id 变泄,也可以設(shè)置成一個(gè)自定義的值

分片的實(shí)時(shí)性和查詢性能
image.png

refresh

Elasticsearch 是基于 Apache Lucene 構(gòu)建的令哟,Lucene 是一個(gè)高性能的全文搜索引擎庫(kù)。在Lucene中妨蛹,索引是由多個(gè)段(segments)組成的屏富,每個(gè)段是一個(gè)獨(dú)立的倒排索引。

  • 段(Segment):一個(gè)段是一個(gè)不可變的倒排索引滑燃,包含了一部分文檔的數(shù)據(jù)役听。段是Lucene索引的基本單位。
  • 內(nèi)存緩沖區(qū)(Memory Buffer):新索引的文檔首先被寫(xiě)入內(nèi)存緩沖區(qū),實(shí)際是就是寫(xiě)入到j(luò)vm中典予。
  • 索引寫(xiě)入器(Index Writer):負(fù)責(zé)將內(nèi)存緩沖區(qū)中的文檔寫(xiě)入新的段甜滨。

refresh 操作的主要目的是將內(nèi)存緩沖區(qū)中的文檔刷新到一個(gè)新的段中,使得這些文檔對(duì)搜索請(qǐng)求可見(jiàn)瘤袖。以下是refresh操作的具體流程

  1. 內(nèi)存緩沖區(qū):
    新索引的文檔首先被寫(xiě)入內(nèi)存緩沖區(qū)(jvm),這個(gè)內(nèi)存緩沖區(qū)是位于jvm中
  2. 段創(chuàng)建:
    當(dāng) refresh 操作被觸發(fā)時(shí)衣摩,內(nèi)存緩沖區(qū)中的文檔被寫(xiě)入一個(gè)新的段,此操作在jvm中進(jìn)行捂敌,所以段的創(chuàng)建也是在jvm中艾扮。
    這個(gè)新的段是一個(gè)不可變的倒排索引,包含了內(nèi)存緩沖區(qū)中的文檔占婉。
  3. 段注冊(cè):
    新創(chuàng)建的段被注冊(cè)到索引的搜索上下文中泡嘴。
    注冊(cè)后,這些文檔對(duì)搜索請(qǐng)求可見(jiàn)逆济。
  4. 內(nèi)存緩沖區(qū)清空:
    內(nèi)存緩沖區(qū)被清空酌予,準(zhǔn)備接收新的文檔。

當(dāng)我們向ES發(fā)送請(qǐng)求的時(shí)候奖慌,es貌似可以在我們發(fā)請(qǐng)求的同時(shí)進(jìn)行搜索抛虫。而這個(gè)實(shí)時(shí)建索引被搜索的過(guò)程實(shí)際上是一次es 索引提交(commit)的過(guò)程,如果這個(gè)提交的過(guò)程直接將數(shù)據(jù)寫(xiě)入磁盤(pán)(fsync)必然會(huì)影響性能简僧,所以es中設(shè)計(jì)了一種機(jī)制建椰,即:默認(rèn)情況下每隔一秒新寫(xiě)入的文檔在jvm中解析寫(xiě)到文件緩存系統(tǒng)之中形成段,這樣避免了比較損耗性能io操作岛马,此時(shí)Lucene才能搜索得到棉姐,數(shù)據(jù)才可以提供搜索。
es默認(rèn)每秒中執(zhí)行一次refresh
默認(rèn)情況下每個(gè)分片會(huì)每秒自動(dòng)刷新一次蛛枚。這就是為什么我們說(shuō) Elasticsearch 是 近 實(shí)時(shí)搜索: 文檔的變化并不是立即對(duì)搜索可見(jiàn)谅海,但會(huì)在一秒之內(nèi)變?yōu)榭梢?jiàn)可搜索。

flush

如果數(shù)據(jù)在文件系統(tǒng)緩存之中是很有可能在意外的故障中丟失蹦浦。這個(gè)時(shí)候就需要一種機(jī)制扭吁,可以將對(duì)es的操作記錄下來(lái),來(lái)確保當(dāng)出現(xiàn)故障的時(shí)候盲镶,保留在文件系統(tǒng)緩存的數(shù)據(jù)不會(huì)丟失侥袜,并在重啟的時(shí)候可以從這個(gè)記錄中將數(shù)據(jù)恢復(fù)過(guò)來(lái)。elasticsearch提供了translog來(lái)記錄這些操作溉贿。就是和數(shù)據(jù)庫(kù)wal思想很像(日志先行)

flush包括:將事務(wù)日志(translog)中的操作持久化到磁盤(pán)(fsync)和清空內(nèi)存中的緩沖區(qū)和事務(wù)日志兩個(gè)流程枫吧。

一個(gè)文檔被索引之后,就會(huì)被添加到內(nèi)存緩沖區(qū)宇色,并且追加到了translog
默認(rèn)每秒refresh一次九杂,refresh會(huì)清空內(nèi)存緩存颁湖,但是不會(huì)清空translog
refresh操作不斷發(fā)生,更多的文檔被添加到內(nèi)存緩沖區(qū)和追加到translog
translog周期性通過(guò)fsync進(jìn)行刷盤(pán)例隆,默認(rèn)5s甥捺,可通過(guò)參數(shù)index.translog.sync_interval、index.translog.durability控制镀层;并且每30分鐘或當(dāng)事務(wù)日志達(dá)到一定大辛獭(512MB)時(shí)自動(dòng)執(zhí)行一次 flush 操作。保證應(yīng)用重啟后先確認(rèn)最后記錄的commit point唱逢,commit point之后的變更操作通過(guò)落盤(pán)的translog進(jìn)行重構(gòu)恢復(fù)段

雖然translog主要保存在內(nèi)存中吴侦,但通過(guò)定期同步到磁盤(pán),確保了數(shù)據(jù)的持久性坞古,如果節(jié)點(diǎn)在兩次同步之間宕機(jī)备韧,內(nèi)存中的translog數(shù)據(jù)可能會(huì)丟失。但是绸贡,由于同步頻率較高(每5秒一次)盯蝴,這種數(shù)據(jù)丟失的風(fēng)險(xiǎn)非常小,如果es的數(shù)據(jù)非常重要听怕,可以通過(guò)index.translog.sync_interval配置縮短日志自動(dòng)的時(shí)間間隔,增加日志刷盤(pán)的頻率虑绵,但會(huì)影響性能尿瞭。如果es的數(shù)據(jù)不是那么重要,更es的性能翅睛,可減少日志刷盤(pán)的頻率

fsync

fsync:每個(gè)新段在文件系統(tǒng)緩存被持久化到磁盤(pán)的過(guò)程叫做fsync

有時(shí)候我們創(chuàng)建了一個(gè)文檔然后嘗試搜索它声搁,但卻沒(méi)有搜到。這個(gè)問(wèn)題的解決辦法是用 refresh API 執(zhí)行一次手動(dòng)刷新:

POST /_refresh  //刷新所有的索引
POST /index_name/_refresh //只刷新(Refresh) 特定索引

es寫(xiě)性能優(yōu)化

降低刷新頻率(會(huì)影響實(shí)時(shí)性)
    1. 提高寫(xiě)性能捕发,我們可以啟動(dòng)多線程去進(jìn)行寫(xiě)操作
    1. 除了啟動(dòng)多線程外還可以通過(guò)調(diào)整刷新頻率來(lái)提升性能疏旨。

雖然刷新(refresh)是比提交輕量很多的操作,但它還是會(huì)有性能開(kāi)銷扎酷,并不是所有的情況都需要每秒刷新檐涝。如果你想優(yōu)化讀寫(xiě)速度而不是近實(shí)時(shí)搜索,可以通過(guò)設(shè)置refresh_interval法挨, 降低每個(gè)索引的刷新頻率:

PUT /my_logs
{
    "settings": {
        "refresh_interval": "30s"  //每30秒刷新 my_logs 索引谁榜,默認(rèn)是每秒刷新
    }
}

refresh_interval 是可以進(jìn)行動(dòng)態(tài)更新的,就是說(shuō)在生產(chǎn)環(huán)境中凡纳,當(dāng)你正在建立一個(gè)大的新索引時(shí)窃植,可以先關(guān)閉自動(dòng)刷新,待開(kāi)始使用該索引時(shí)荐糜,再把它們調(diào)回來(lái):

PUT /my_logs/_settings
{ "refresh_interval": -1 } //關(guān)閉實(shí)時(shí)更新

PUT /my_logs/_settings
{ "refresh_interval": "1s" }//開(kāi)啟每秒更新

refresh_interval 需要一個(gè) 持續(xù)時(shí)間 值巷怜, 例如 1s (1 秒) 或 2m (2 分鐘)葛超。 一個(gè)絕對(duì)值 1 表示的是 1毫秒 (會(huì)使你的集群陷入癱瘓)。

    1. 修改內(nèi)存緩存大小(indices.memory.index_buffer_size)延塑。

jvm內(nèi)存緩存的數(shù)據(jù)滿了或者是超過(guò)固定時(shí)間就會(huì)進(jìn)行刷新操作绣张,調(diào)整內(nèi)存緩存大小可以有效的降低刷新頻率
在elasticsearch.yml中可以這樣設(shè)置:

indices.memory.index_buffer_size: 20%(默認(rèn)是堆內(nèi)存的10%)
indices.memory.min_index_buffer_size: 96mb(默認(rèn)是48mb)

已經(jīng)索引好的文檔會(huì)先存放在內(nèi)存緩存中,等待被寫(xiě)到到段(segment)中页畦。緩存滿的時(shí)候會(huì)觸發(fā)段刷盤(pán)(吃i/o和cpu的操作)胖替。默認(rèn)最小緩存大小為48m,不太夠豫缨,最大為堆內(nèi)存的10%独令。對(duì)于大量寫(xiě)入的場(chǎng)景也顯得有點(diǎn)小。

    1. 修改事務(wù)日志(translog)的刷新頻率(fsync)(index.translog.sync_interval)和大泻冒拧(index.translog.flush_threshold_size)

日志中記錄了還在緩存中并未形成段的數(shù)據(jù)燃箭,會(huì)定時(shí)或者超過(guò)一定量后進(jìn)行刷新
在elasticsearch.yml中可以這樣設(shè)置:

index.translog.sync_interval:30s(默認(rèn)5s)。
index.translog.flush_threshold_size:700mb(默認(rèn)512mb)
index.translog.durability:async(默認(rèn)request) //通過(guò)異步提交日志舍败,不過(guò)可以會(huì)在宕機(jī)時(shí)丟失數(shù)據(jù)
    1. _id字段的使用招狸,應(yīng)盡可能避免自定義_id, 以避免針對(duì)ID的版本管理;建議使用ES的默認(rèn)ID生成策略或使用數(shù)字類型ID做為主鍵邻薯。

es讀性能優(yōu)化

  • 1.合理的分片的數(shù)量裙戏,分片數(shù)量越多每個(gè)分片的數(shù)據(jù)范圍就越小,合理的分片數(shù)量能有效的提升每個(gè)分片的查詢性能

  • 2. 遵循通用的原則厕诡, 4~32G的內(nèi)存給ES即可累榜,其余留給lucene。內(nèi)存對(duì)于 Elasticsearch 來(lái)說(shuō)絕對(duì)是重要的灵嫌,它可以被許多內(nèi)存數(shù)據(jù)結(jié)構(gòu)使用來(lái)提供更快的操作壹罚。但是另外一個(gè)內(nèi)存消耗大戶 非堆內(nèi)存 (off-heap)的Lucene是用于索引的關(guān)鍵

  • 關(guān)閉交換分區(qū),防止內(nèi)存發(fā)生交換導(dǎo)致性能下降 通過(guò)執(zhí)行swapoff -a或者通過(guò): 在elasticsearch.yml 中 bootstrap.memory_lock: true寿羞, 以保持JVM鎖定內(nèi)存猖凛,保證ES的性能晃洒。

es的鎖機(jī)制

由于es需要處理一定的并發(fā)量的寫(xiě)操作修肠,es是使用的樂(lè)觀鎖,主要是使用java的CAS技術(shù)實(shí)現(xiàn)樂(lè)觀鎖

正排索引

就是利用文檔id查詢文檔內(nèi)容,也就是通過(guò)key去查value

倒排索引

就是通過(guò)value去查key,關(guān)于倒排索引這里有一篇不錯(cuò)的文章可以供大家參考https://blog.csdn.net/qq_21312297/article/details/102496833

es索引的過(guò)程

es是先通過(guò)term Dictionary將每個(gè)單詞出現(xiàn)在文檔的位置地址這個(gè)過(guò)程是倒排索引唉铜,然后通過(guò)地址去查詢文檔霞幅,這個(gè)是正排索引漠吻,es就是倒排索引和正排索引的結(jié)合

term Dictionary(單詞字典):記錄了所有文檔的單詞,es儲(chǔ)存的文檔內(nèi)容越大詞典也就越大司恳,還記錄了單詞是放在哪些文檔上的關(guān)聯(lián)信息途乃,通常term Dictionary會(huì)被拆分成單詞的前綴組成一顆B+樹(shù),每個(gè)葉子節(jié)點(diǎn)的單詞會(huì)記錄著單詞所在文檔的位置地址

Posting List:記錄了單詞對(duì)應(yīng)文檔的集合扔傅,由Posting組成耍共,而Posting中包含了文檔id,單詞出現(xiàn)頻率烫饼,文檔中單詞的位置,單詞在文檔開(kāi)始和結(jié)束的位置

以下是倒排索引的過(guò)程
文檔字段類型
核心類型 字符串類型 string,text,keyword
整數(shù)類型 integer,long,short,byte
浮點(diǎn)類型 double,float,half_float,scaled_float
邏輯類型 boolean
日期類型 date
范圍類型 range
二進(jìn)制類型 binary
復(fù)合類型 數(shù)組類型 array
對(duì)象類型 object
嵌套類型 nested
地理類型 地理坐標(biāo)類型 geo_point
地理地圖 geo_shape
特殊類型 IP類型 ip
范圍類型 completion
令牌計(jì)數(shù)類型 token_count
附件類型 attachment
抽取類型 percolator

基礎(chǔ)語(yǔ)句

以下省略 http://localhost:9200

index操作

創(chuàng)建index:

put  /index_name
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}

查看index:

get  /_cat/indices

刪除index:

delete /index_name
document操作

創(chuàng)建id為2的文檔:

DELETE /index_name/doc/2

創(chuàng)建id為1的文檔:

put /index_name/_doc/1
{
"name":"es",
"user":"test"
}

創(chuàng)建自帶id的文檔:

post /index_name/_doc/
{
"name":"es",
"user":"test"
}

_routing:
如果在創(chuàng)建mapping時(shí)設(shè)置了_routing為true,那么創(chuàng)建文檔的時(shí)候必須帶上routing,否則出錯(cuò):

post /index_name/_doc?routing=xxxxx
{
"name":"es",
"user":"test"
}

post /index_name/_doc/1?routing=xxxxx
{
"name":"es",
"user":"test"
}

批量創(chuàng)建文檔:

put /u/_bulk
{"index":{"_id":3}}
{"username":"james","code":23,"age":32,"country":"usa","job":"basketball"}
{"index":{"_id":4}}
{"username":"haden","code":15,"age":30,"country":"usa","job":"basketball"}
{"index":{"_id":5}}
{"username":"bingbing","code":999,"age":35,"country":"chn","job":"act"}
{"index":{"_id":6}}
{"username":"susu","code":999,"age":25,"country":"chn","job":"great"}
{"index":{"_id":7}}
{"username":"hu","code":999,"age":36,"country":"chn","job":"act"}

批量修改文檔:

POST _bulk
{"update":{"_index":"test","_type":"product","_id":1}}
{"doc":{ "price" : 5200, "productName" : "蘋(píng)果11","memory":"128G" }}
{"update":{"_index":"test","_type":"product","_id": 2 }}
{"doc":{ "price" : 3100, "productName" : "小米10","memory":"268G" }}
{"update":{"_index":"test","_type":"product", "_id": 3 }}
{"doc":{ "price" : 1300, "productName" : "酷派大神","memory":"16G" }}
{"update":{"_index":"test","_type":"product", "_id": 4 }}
{"doc":{ "price" : 730, "productName" : "魅藍(lán)note3","memory":"32G" }}
{"update":{"_index":"test","_type":"product", "_id": 6 }}
{"doc":{ "price" : 10000, "productName" : "macBook Pro","memory":"521G" }}
{"update":{"_index":"test","_type":"product", "_id": 7 }}
{"doc":{ "price" : 6500, "productName" : "華為P40","memory":"128G" }}
{"update":{"_index":"test","_type":"product","_id": 8 }}
{"doc":{ "price" : 3100, "productName" : "Ipad Air3","memory":"64G" }}

批量查詢:

post /_mget
{
    "docs": [
        {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1"
        },
        {
            "_index": "test_index",
            "_type": "doc",
            "_id": "Ai9cM3IBEyMN0HxifBpI"
        }
    ]

修改文檔:

POST /u/_doc/5/_update
{
   "doc":{
    "age":41,
    "username":"kate"
   }
}

根據(jù)查詢的結(jié)果更改文檔字段:

POST /u/_doc/_update_by_query
{
    "script":{
    "source":"ctx._source['brith']='1990-11-11 12:00:00'"
    },
   "query":{
    "match_all":{
    }
   }
}

新增文檔字段:

PUT /u/_mapping
{
   "properties":{
    "brith":{
        "type":"date",
        "format": "yyyy-MM-dd HH:mm:ss"
    }
   }
}
分詞器

分詞就是將文本轉(zhuǎn)化為一系列單詞的過(guò)程试读,也叫做文本分析杠纵,在es中稱為Analysis,es默認(rèn)的Analysis是standard
Analysis由三部分組成:
Character Filters:對(duì)原始文本進(jìn)行處理,去掉一些特殊的符號(hào)標(biāo)簽钩骇,例如去除html的特殊標(biāo)記符
Tokenizer:將原始文本按照一定的規(guī)則切分成單詞
Toker Filters:對(duì)Tokenizer處理的單詞進(jìn)一步加工比藻,例如大小寫(xiě)轉(zhuǎn)換,刪除沒(méi)有意義的詞等

分詞器選擇并測(cè)試:

post /_analyze
{
   "analyzer":"simple",//選擇simple分詞器
   "text":"elasticsearch是世界最好的搜索引擎"
    
}

es內(nèi)置分詞器:
Standard - 默認(rèn)分詞器倘屹,按詞切分银亲,小寫(xiě)處理
Simple - 按照非字母切分(符號(hào)被過(guò)濾), 小寫(xiě)處理
Stop - 小寫(xiě)處理,停用詞過(guò)濾(the,a,is)
Whitespace - 按照空格切分纽匙,不轉(zhuǎn)小寫(xiě)
Keyword - 不分詞务蝠,直接將輸入當(dāng)作輸出
Patter - 正則表達(dá)式,默認(rèn)\W+(非字符分割)
Language - 提供了30多種常見(jiàn)語(yǔ)言的分詞器
Customer 自定義分詞器

中文分詞器:
IK - 支持中英文單詞分詞烛缔,支持ik_smart,ik_maxword的模式馏段,支持自定義詞庫(kù)、支持熱更新單詞詞典
jieba - python最流行的分詞器践瓷,支持繁體分詞院喜,自定義詞典等

Mapping

Mapping類似數(shù)據(jù)庫(kù)表數(shù)據(jù)類型定義,Mapping可以定義index下的字段名晕翠,字段類型够坐。mapping創(chuàng)建后不支持修改和刪除字段,只支持添加新字段

動(dòng)態(tài)mapping

在mapping中有dynamic屬性崖面,默認(rèn)是true,代表著動(dòng)態(tài)mapping梯影,在動(dòng)態(tài)mapping下我們插入的文檔巫员,es會(huì)為我們自動(dòng)識(shí)別文檔中的字段類型,然后為我們創(chuàng)建相應(yīng)的字段類型甲棍,下面是es自動(dòng)識(shí)別后為我們創(chuàng)建的字段類型

動(dòng)態(tài)mapping可以降低用戶的使用es的成本

靜態(tài)mapping

當(dāng)我們創(chuàng)建mapping時(shí)并指定dynamic屬性為false简识,代表著靜態(tài)mapping,在靜態(tài)mapping下如果我們插入了mapping中沒(méi)有定義的字段就會(huì)自動(dòng)的進(jìn)行忽略感猛,忽略的意思就是插入沒(méi)有定義的字段可以正常插入七扰,但是搜索的時(shí)候會(huì)把字段給忽略了,查出來(lái)的結(jié)果不會(huì)包含mapping中不存在的字段并且這些字段也不支持索引

strict mapping

當(dāng)我們把mapping設(shè)置為strict時(shí)陪白,如果我們插入了mapping中沒(méi)有定義的字段就會(huì)直接報(bào)錯(cuò)

index設(shè)置

mapping字段中的index字段代表著是否可以用來(lái)做搜索颈走,默認(rèn)是true

null_values

mapping字段中的null_values字段代表著字段遇到null時(shí)做怎么樣的處理,es默認(rèn)字段遇到null時(shí)會(huì)自動(dòng)忽略

doc_values

字段的 doc_values 屬性有兩個(gè)值咱士, true立由、false轧钓。默認(rèn)為 true ,即開(kāi)啟锐膜。
當(dāng) doc_values 為 fasle 時(shí)毕箍,無(wú)法基于該字段排序、聚合道盏、在腳本中訪問(wèn)字段值而柑。
當(dāng) doc_values 為 true 時(shí),ES 會(huì)增加一個(gè)相應(yīng)的正排索引荷逞,這增加的磁盤(pán)占用媒咳,也會(huì)導(dǎo)致索引數(shù)據(jù)速度慢一些。

查看mapping

GET /index_name/_mapping

創(chuàng)建索引同時(shí)定義mapping

PUT /index_name
{
  "settings": {
    "number_of_shards": 4,
    "number_of_replicas": 1
  },
  "mappings": {
      "dynamic": "false",//定義mapping是否允許動(dòng)態(tài)生成颅围,默認(rèn)是true伟葫,還有一個(gè)strict,strict下插入沒(méi)有定義的字段會(huì)直接報(bào)錯(cuò)
      "_routing": {
        "required": true  
      },
      "properties": {
        "account": {
          "type": "keyword"院促,
          "null_values":"暫無(wú)"  //遇到null時(shí)顯示為暫無(wú)筏养,es默認(rèn)遇到null會(huì)自動(dòng)忽略
        },
        "firstname": {
          "type": "keyword"
        },
        "nikename": {
          "type": "keyword"
        },
        "create_time":{
        "type":"date",
        "format":"MM/dd/yyyy"  
        },
        "obj_id": {
          "type": "keyword",
          "index": false, //是否支持索引,默認(rèn)是true
          "doc_values": false //false時(shí)不支持排序聚合
        },
        "bypass": {
          "properties": {
            "id": {
              "type": "keyword"
            },
            "vpnmtype": {
              "type": "keyword"
            },
            "vpnstype": {
              "type": "keyword"
            }
          }
        },
        "caller_type": {
          "type": "keyword"
        },
       "contend": {
          "type": "text",
          "fields": {       //子字段類型常拓,索引時(shí)可以使用contend.keyword
            "keyword": {
              "type": "keyword"
            }
          },
          "analyzer": "ik_smart"
        },
      
.......

Search API

URI Search

q:指定URL查詢條件
df(default field):指定查詢的字段渐溶,如果不寫(xiě),es 會(huì)查詢所有字段或者是q中指定的字段
sort:排序
timeout:指定超時(shí)時(shí)間弄抬,默認(rèn)不超時(shí)
from茎辐,size:用于分頁(yè)

GET /u/_search?q=basketball
GET /u/_search?q=job:basketball mvp//查詢出所有job是basketball和mvp的文檔
GET /u/_search?q=job:"basketball mvp"http://查詢出所有job是basketball mvp的文檔
GET /u/_search?q=job:(basketball mvp)//查詢job:basketball或者job:mvp
GET /u/_search?q=user.id:8a4f500d
GET /u/_search?q=basketball&df=job&sort=age:asc&from=1&size=3&timeout=1s//df指定q的值basketball從job字段查,分頁(yè)從第一頁(yè)開(kāi)始掂恕,每頁(yè)3條記錄拖陆,查詢時(shí)間不能超過(guò)1秒,超過(guò)一秒就退出查詢
布爾操作:

要大寫(xiě)懊亡,不能小寫(xiě)
AND:&&
OR:||
NOT:!

GET /u/_search?q=basketball AND mvp //查詢出所有包含basketball 并且同時(shí)有mvp 的字段
GET /u/_search?q=job:(basketball AND mvp)//查詢出所有job是basketball并且有mvp的文檔
GET /u/_search?q=job:(basketball NOT mvp)//查詢出所有job是basketball并且沒(méi)有mvp的文檔
GET /u/_search?q=job:(basketball || mvp)//查詢出所有job是basketball或者有mvp的文檔
{
    "profile":true"http://查看es查詢的過(guò)程
}
加減操作

+:在url寫(xiě)成%2B必須有 must
-:必須沒(méi)有 must_not

GET /u/_search?q=basketball  %2Bmvp//查詢出所有是basketball 并且一定包含mvp的文檔
GET /u/_search?q=(basketball  %2Bmvp)//查詢出所有是basketball 并且一定包含mvp的文檔
GET /u/_search?q=basketball -2Bmvp//查詢出所有是basketball 并且一定不包含mvp的文檔
GET /u/_search?q=job:(basketball -2Bmvp)//查詢出所有job是basketball 并且一定不包含mvp的文檔
范圍查詢

閉區(qū)間 [ ] 開(kāi)區(qū)間{ }
age:[1 TO 10]相當(dāng)于1<=age<=10
age:[1 TO 10}相當(dāng)于1<=age<10
age:[1 TO ]相當(dāng)于age>=1
age:[* TO 10]相當(dāng)于age<=10

GET /u/_search?q=basketball AND mvp age:>31 //查詢出所有包含basketball 并且同時(shí)有mvp 的字段或者age大于31
GET /u/_search?q=basketball AND mvp AND age:>31//查詢出所有包含basketball 并且同時(shí)有mvp 的字段并且age大于31
通配符查詢

username:j?mes:匹配任意一個(gè)字符
username:jam*:匹配任意多個(gè)字符
username:j*s:匹配任意多個(gè)字符

GET /u/_search?q=j*s
GET /u/_search?q=username:j*s
GET /u/_search?q=j?mes

wildcard

wildcard類似上的模糊查詢依啰,相應(yīng)于GET /u/_search?q=j*s的 DSL寫(xiě)法

post /u/_search
{
    "query": {
        "wildcard": {
            "username.keyword":"j*s" 
        }
    }
}
正則表達(dá)式查詢

這個(gè)需要對(duì)正則表達(dá)的掌握能力,舉兩個(gè)例子

GET /u/_search?q=username:/j.{1,}/
GET /u/_search?q=username:/[張李].*亭{1,}.*/

query DSL 的寫(xiě)法

post /u/_search
{
    "query": {
        "regexp": {
            "username":"j.*" 
        }
    }
    
}
模糊匹配查詢
GET /u/_search?q=job:basketball~1 //查詢job中與basketball相差1個(gè)char值的文檔店枣,例如basketball 速警、basketball mvp
近似度查詢
GET /u/_search?q=job:“basketball mvp“~1 //匹配到basketball mvp 前后中間可以允許插入1個(gè)詞 basketball xxxx mvp\basketball mvp xxxx\xxxx basketball mvp都會(huì)匹配到,

Request Body Search

query DSL

字段查詢

1鸯两、全文匹配

對(duì)text類型的字段查詢時(shí)闷旧,會(huì)先分詞

  • match:
    分詞后詞語(yǔ)沒(méi)有先后順序,隨意組合钧唐,這個(gè)適合非常適用于關(guān)鍵詞全文檢索
select * from u where job like '%basketball%' or job like '%mvp%'

post /u/_search
{
    "profile":true,//查看es查詢的過(guò)程
    "query":{
        "match":{
            "job":"basketball mvp"http://job字段查詢即包含basketball 或者包含mvp的文檔
        }
    }
}
select * from u where job like '%basketball%' and job like '%mvp%'

post /u/_search
{
    "query": {
        "match":{
            "job":{
                "query":"basketball mvp",//job必須同時(shí)包含basketball和mvp
                "operator":"and"http://默認(rèn)是or
            }
        }
    }
}
post /u/_search
{
    "query": {
        "match":{
            "job":{
                "query":"basketball mvp act",
                "minimum_should_match":"2"http://搜索出job字段中至少包含關(guān)鍵詞其中兩個(gè)才會(huì)匹配上
            }
            
        }
    }
}
  • match_all:
select * from u

post /u/_search
{
  "query": {
    "match_all": {}
  }
}
  • match_phrase:
    分詞后詞語(yǔ)存在先后順序
    1. match_phrase還是分詞后去搜的
    2. 目標(biāo)文檔需要包含分詞后的所有詞
    3. 目標(biāo)文檔還要保持這些詞的相對(duì)順序和文檔中的一致
    4. match_phrase的缺點(diǎn)就是性能比較差

以"hello world"為例忙灼,要求結(jié)果中必須包含hello和world,而且還要求他們是連著的逾柿,順序也是固定的缀棍,hello that word不滿足宅此,world hello也不滿足條件。

post /u/_search
{
    "query": {
        "match_phrase":{
            "job":"basketball mvp"http://查詢包含basketball mvp的文檔爬范,
//與term不同的是term是從索引的單詞找父腕,match_phrase從文檔的單詞找
        }
    }
}
post /u/_search
{
    "query": {
        "match_phrase":{
            "job":{
                "query":"basketball act",
                "slop":"1"http://允許文檔出現(xiàn)和搜索條件相差一個(gè)距離的文檔
       // 例如這里會(huì)匹配到 basketball xxxx act/basketball act xxxx/xxxx basketball act
            }
        }
    }
}
  • query_string:
    這個(gè)關(guān)鍵詞和match類似,只是query_string更加暴力是所有字段中搜索范圍更廣泛青瀑。match則是需要指定字段的搜索的璧亮。但是query_string也可以指定字段并且可以使用and or等關(guān)鍵詞,不指定字段默認(rèn)全字段搜索斥难,性能會(huì)很差
post /u/_search
{
    "query": {
        "query_string":{
            "query":"basketball AND act"http://匹配所有的字段中即有basketball又有act的文檔
        }
    }
}
post /u/_search
{
    "query": {
        "query_string":{
                "default_field":"job",//匹配job字段中即有basketball又有act的文檔
            "query":"basketball AND act"
        }
    }
}
post /u/_search
{
    "query": {
        "query_string":{
                "fields":["job","username"],//只匹配job和username字段,并且每個(gè)字段都必須包含james 和 act
                "query":"james and act"
        }
    }
}

2枝嘶、精確查詢

  • term、terms:將查詢語(yǔ)句作為一個(gè)單詞查詢哑诊,不做分詞處理,查詢時(shí)字段必須完全匹配包括長(zhǎng)度順序內(nèi)容群扶。使用這類關(guān)鍵詞時(shí)字段的類型不要使用text,應(yīng)當(dāng)使用keyword類型,如果字段是text類型的話镀裤,我們查詢時(shí)需要這樣寫(xiě): xxxx.keyword
select * from u where job="basketball mvp"

post /u/_search
{
    "query": {
        "term":{
            "job.keyword":"basketball mvp"http://這里在倒排索引中匹配basketball mvp
//最終的結(jié)果是匹配不到任何文檔竞阐,因?yàn)樗饕卸际且粋€(gè)個(gè)被切分了的單詞不存在“basketball mvp”
        }
    }
}
select * from u where job in ('basketball', 'mvp')

post /u/_search
{
    "query": {
        "terms":{
            "job.keyword":["basketball","mvp"]
        }
    }
}

3、范圍暑劝、排序骆莹、分頁(yè)

  • range: 范圍查詢 lt:小于、lte:小于等于担猛、gt:大于幕垦、gte大于等于
select * from u where age between 30 and 40;

post /u/_search
{
  "query" : {  
    "range" : {
      "age" : { 
        "gte" : 30,
        "lte" : 40
      }
    }
  }
}
  • sort,from,size:
POST /test/product/_search
{
  "query":{
    "match": {
      "productName":"蘋(píng)果小米華為"
    }
    
  },
  "sort":{"price":"desc"},
  "from":2,
  "size":3
}

scroll:深分頁(yè),對(duì)于上面介紹的淺分頁(yè),如果請(qǐng)求的頁(yè)數(shù)較少(假設(shè)每頁(yè)20個(gè)docs), Elasticsearch不會(huì)有什么問(wèn)題,但是如果頁(yè)數(shù)較大時(shí),比如請(qǐng)求第1000頁(yè)傅联,Elasticsearch不得不取出第1頁(yè)到第1000頁(yè)的所有docs先改,再去除第1頁(yè)到第999頁(yè)的docs,得到第1000頁(yè)的docs蒸走。解決的方式就是使用scroll盏道,scroll就是維護(hù)了當(dāng)前索引段的一份快照信息--緩存

初始化的時(shí)候就像是普通的search一樣 其中的scroll=3m代表當(dāng)前查詢的數(shù)據(jù)緩存3分鐘

POST test/_search?scroll=3m
{
  "query":{
    "match_all": {}
  }
}

在遍歷時(shí)候,拿到上一次遍歷中的_scroll_id载碌,然后帶scroll參數(shù),3m代表重置過(guò)期時(shí)間

POST /_search/scroll
{
  "scroll" : "3m",
  "scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFjlxTWE1RTZwUmdpd3FZSkpsYm5kYXcAAAAAAAA-vxZBRWtUWDAyalM5YTZvbmx0YTJxQjZR"
}
相關(guān)性得分(_score)

依據(jù):

  • 詞頻:單詞在該文檔出現(xiàn)的頻率越高,相關(guān)性越高
  • 文檔長(zhǎng)度:文檔越短衅枫,相關(guān)性越高
  • 包含單詞文檔數(shù)量:文檔包含某個(gè)單詞的數(shù)量越少嫁艇,相關(guān)性越高

復(fù)合查詢

constant_score:

默認(rèn)將其查詢結(jié)果的文檔得分都設(shè)置為1(如果不指定boost的話)或者指定boost的值,這個(gè)是當(dāng)我們不關(guān)心檢索詞頻率TF(Term Frequency)對(duì)搜索結(jié)果排序的影響時(shí)使用(簡(jiǎn)單了說(shuō)就是不在乎得分)

POST /test/product/_search
{
  "query":{
    "constant_score": {
      "filter": {
        "match":{
          "productName":"華為"
        }
      },
      "boost": 1
    }
  }
}
GET test_index/_search
{
    "query": {
        "constant_score": {
            "boost": 1.0,
            "filter": {
                "bool": {
                    "must": [
                        {
                            "terms": {
                                "qq": [
                                  "7823709637249",
                                  "7828688362980"
                                    ]
                            }
                        }
                    ]
                }
            }
        }
    }
}

bool:

  • filter:使用filter查詢時(shí)會(huì)有緩存,所以其效率很高弦撩,如果不使用相關(guān)性得分的排排序步咪,推薦使用filter
 post /u/_search
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "job.keyword": "basketball"
                }
            }
        }
    }
}
 post /u/_search
{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "job": "basketball"
                    }
                },
                {
                    "match": {
                        "job": "act"
                    }
                }
            ]
        }
    }
}
  • must:
 post /u/_search
//查詢文檔中的job字段必須同時(shí)包含basketball和act
{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "job": "basketball"
                    }
                },
                {
                    
                    "match": {
                        "job": "act"
                    }
                }
            ]
        }
    }
}
  • must_not:
 post /u/_search
//查詢文檔中的job字段必須同時(shí)包含basketball和act,而要求必須不能有mvp
{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "job": "basketball"
                    }
                },
                {
                    "match": {
                        "job": "act"
                    }
                }
            ],
            "must_not": [
                {
                    "match": {
                        "job": "mvp"
                    }
                }
            ]
        }
    }
}
  • should:默認(rèn)至少滿足一個(gè)條件,可以通過(guò)minimum_should_match控制滿足個(gè)數(shù)
 post /u/_search
//查詢滿足其中之一的查詢即可益楼,也就是job中包含basketball或者act或者mvp其中一個(gè)就能查詢出來(lái)
{
    "query": {
        "bool": {
            "should": [
                {
                    "term": {
                        "job": "basketball"
                    }
                },
                {
                    "match": {
                        "job": "act"
                    }
                },
                {
                    "match_phrase": {
                        "job": "basketball mvp"
                    }
                }
            ]
        }
    }
}
 post /u/_search
{
    "query": {
        "bool": {
            "should": [
                {
                    "term": {
                        "job": "basketball"
                    }
                },
                {
                    "match": {
                        "job": "act"
                    }
                },
                {
                    "match_phrase": {
                        "job": "basketball mvp"
                    }
                }
            ]猾漫,
 "minimum_should_match":3//設(shè)置了滿足條件為3
//查詢結(jié)果同時(shí)滿足其中三個(gè)也就job中包含basketball并且包含act和mvp就能查詢出來(lái)都
        }
    }
}
  • should與must\must_not:查詢時(shí)必須滿足或者必須不滿足must/must_not,可以不滿足should点晴,如果可以滿足should也一并查出
 post /u/_search
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "job": "act"
                    }
                }
            ],
            "must": [
                {
                    "match":{
                        "job":"mvp"
                    }
                }
            ]
        }
    }
}

should+must+filter

{
    "query": {
        "bool": {
            "filter": [
                {
                    "bool": {
                        "must": [
                            {
                                "terms": {
                                    "boost": 1.0,
                                    "msisdn": [
                                        "7823709637249",
                                        "7828603061831",
                                        "7827817096436"
                                    ]
                                }
                            },
                            {
                                "range": {
                                    "ts_m": {
                                        "from": 1583622000017,
                                        "to": 1618902000017
                                    }
                                }
                            },
                            {
                                "bool": {
                                    "should": [
                                        {
                                            "terms": {
                                                "app_id": [
                                                    "0"
                                                ],
                                                "boost": 1.0
                                            }
                                        },
                                        {
                                            "terms": {
                                                "host": [
                                                    "res.wx.qq.com",
                                                    "bluedot.is.autonavi.com.gds.alibabadns.com"
                                                ]
                                            }
                                        },
                                        {
                                            "match": {
                                                "col10": {
                                                    "query": "品種貓 部門(mén) 蛾子 劉微球"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}
  • source:只希望返回個(gè)別字段即可
//只希望查詢時(shí)返回username字段
GET /u/_search?_source=username

Count API

獲取符合查詢條件的文檔數(shù)量
查詢語(yǔ)句和上面的一樣只是把URL修改了

post /u/_count
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "job": "act"
                    }
                }
            ],
            "must": [
                {
                    "match":{
                        "job":"mvp"
                    }
                }
            ]
        }
    }
}

排序、分頁(yè)滾動(dòng)

sort

  • 數(shù)字類型排序遍歷
    單字段排序
 post /u/_search
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "job": "act"
                    }
                }
            ],
            "must": [
                {
                    "match": {
                        "job": "mvp"
                    }
                }
            ]
        }
    },
    "sort": {
        "age": "desc"http://按照年齡倒敘排序
    }
}

多字段排序

 post /u/_search
{
    "query": {
        "match": {
            "job": "basketball"
        }
    },
    "sort": [
        {
            "age": "desc"
        },
        {
            "_score": "desc"
        }
    ]
}
  • 字符串類型排序
    按照字符串類型排序時(shí)不能排序text類型的悯周,只能排序keyword的類型粒督,所以在排序text類型時(shí)可以使用text.keyword的方式或者使用設(shè)置fielddata的屬性,例如如下面的查詢
post /u/_search
//text.keyword的方式
{
    "query": {
        "match": {
            "job": "basketball"
        }
    },
    "sort": {
        "username.keyword":"asc"
    }
}

設(shè)置fielddata為true

post /u/_mapping
{
   "properties":{
    "job":{
        "type":"text",
        "fielddata": true
    }
   }
}

然后直接進(jìn)行text排序

POST /u/_search
{
    "query": {
        "match": {
            "job": "basketball"
        }
    },
    "sort": {
        "job":"asc"
    }
}
  • 分頁(yè)
    from:開(kāi)始位置 es默認(rèn)不超過(guò)過(guò)
    size:獲取的總數(shù)
    es默認(rèn)不支持深分頁(yè)換種說(shuō)法就是es不支持大容量的分頁(yè)禽翼,默認(rèn)from+size不能超過(guò)10000
post /u/_search
{
   "from":9996,
   "size":4//from或者size再設(shè)置大一點(diǎn)就會(huì)報(bào)錯(cuò)
}
  • Scroll 分頁(yè)滾動(dòng)屠橄、遍歷
    利用Scroll可以改變分頁(yè)查詢中不能做深分頁(yè)的缺點(diǎn),Scroll查詢方式的原理就是通過(guò)每次查詢后闰挡,返回一個(gè)scroll_id锐墙。根據(jù)這個(gè)scroll_id 進(jìn)行下一頁(yè)的查詢〕ば铮可以把這個(gè)scroll_id理解為通常關(guān)系型數(shù)據(jù)庫(kù)中的游標(biāo)溪北。scroll查詢的數(shù)據(jù)是當(dāng)前索引段的一份快照信息–緩存,所以scroll沒(méi)有實(shí)時(shí)性
//創(chuàng)建一個(gè)scroll設(shè)置夺脾,并且設(shè)置存活時(shí)間是兩分鐘之拨,也就是快照存活2分鐘
GET /u/_search?scroll=2m    
{
  "query": {"match_all": {}},
   "size": 1//設(shè)置每次滾動(dòng)取1條數(shù)據(jù),結(jié)果會(huì)返回
}
image.png

拿著scroll_id可以進(jìn)行滾動(dòng)

//滾動(dòng)scroll
POST /_search?scroll
{
    "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAANAWb1IxVjQ0cFBUMy1jb1dFZUdRbDNKdw==",
    "scroll":"5m"
}
  • Search After分頁(yè)滾動(dòng)、遍歷
    利用Search After可以解決Scroll不能實(shí)時(shí)滾動(dòng)的缺點(diǎn)劳翰,但是Search After只能往下滾動(dòng)敦锌,只支持向下滾動(dòng),不支持向上滾動(dòng)佳簸,并且創(chuàng)建Search After必須要給文檔排序
post /u/_search
{
    "size":1,
   "sort":{
    "age":"desc"
   }
}
image.png

將返回結(jié)果的sort中的值設(shè)置到滾動(dòng)語(yǔ)句中乙墙,上圖是56,設(shè)置search_after為56

GET /u/_search
{
    "size":1,
    "search_after":[56],
   "sort":{
    "age":"desc"
   }
}

總結(jié)分頁(yè)的使用場(chǎng)景


Aggregation 聚合查詢

格式:

多用于統(tǒng)計(jì)使用的生均,舉個(gè)例子
例如統(tǒng)計(jì)從事各類職業(yè)的人數(shù)有多少

GET /u/_search
{
    "size": 0,
    "aggs": {
        "tj": {
            "terms": {
                "field": "job.keyword"
            }
        }
    }
}

返回結(jié)果

    "aggregations": {
        "tj": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 2,
            "buckets": [
                {
                    "key": "act",
                    "doc_count": 2
                },
                {
                    "key": "act av",
                    "doc_count": 2
                },
                {
                    "key": "basketball",
                    "doc_count": 2
                },
               ........
            ]
        }
    }

聚合查詢做的就是類似上面的事情听想,聚合查詢分為4大類分別為:

  • Bucket:分析統(tǒng)計(jì)類型,類似數(shù)據(jù)庫(kù)的group by
  • Metric:指標(biāo)類型,統(tǒng)計(jì)如最大值马胧,最小值汉买,平均值等
  • Pipeline:管道分析類型,基于上一級(jí)分析的結(jié)果進(jìn)行再次分析
  • Matrix:矩陣分析類型佩脊,是es的多維度分析

Bucket

bucket的作用類似數(shù)據(jù)庫(kù)的分組蛙粘,把不同的分析結(jié)果裝到幾個(gè)桶里

  • terms:按照詞語(yǔ)分桶威彰,分桶字段如果是keyword不會(huì)進(jìn)行分詞慨代,直接按照整個(gè)單詞分桶债鸡,如果是text則會(huì)先分詞在分桶晶密,不過(guò)使用text進(jìn)行聚合需要設(shè)置fielddata為true
GET /u/_search
{
    "aggs": {
        "aggs_bulk": {
            "terms": {
                "field": "job.keyword",
                "size":3//指定返回的個(gè)數(shù)
            }
        }
    }
}

返回結(jié)果

 "aggregations": {
        "aggs_bulk": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 11,
            "buckets": [
                {
                    "key": "act",
                    "doc_count": 2
                },
                {
                    "key": "act av",
                    "doc_count": 2
                },
                {
                    "key": "basketball",
                    "doc_count": 2
                }
            ]
        }
    }
  • range
    范圍聚合,統(tǒng)計(jì)數(shù)據(jù)指定范圍的數(shù)量
GET /u/_search
{
    "aggs": {
        "aggs_range": {
            "range": {
                "field": "age",
                "ranges": [
                    {
                        "to": 36//統(tǒng)計(jì)年齡小于36的人數(shù)
                    },
                    {
                        "from": 35,
                        "to": 41
                    }//統(tǒng)計(jì)年齡35.0-41.0之間的人數(shù)
                ]
            }
        }
    }
}

返回結(jié)果

 "aggregations": {
        "aggs_range": {
            "buckets": [
                {
                    "key": "*-36.0",
                    "to": 36.0,
                    "doc_count": 9
                },
                {
                    "key": "35.0-41.0",
                    "from": 35.0,
                    "to": 41.0,
                    "doc_count": 7
                }
            ]
        }
    }
  • date range
    指定日期范圍的分桶
GET monitor_temp/_search
{
    "aggs": {
        "aggs_range": {
            "date_range": {
                "field": "ts_m",
                "format":"yyyy-MM-dd HH:mm:ss",
                "ranges": [
                    {
                        "from":"2020-04-01 00:00:00",
                        "to": "2020-04-30 12:00:00"
                    },
                    {
                      "from":"2020-05-01 00:00:00",
                        "to": "2020-05-30 12:00:00"
                    }
                ]
            }
        }
    }
}

返回部分結(jié)果

 "aggregations" : {
    "aggs_range" : {
      "buckets" : [
        {
          "key" : "2020-04-01 00:00:00-2020-04-30 12:00:00",
          "from" : 1.5856992E12,
          "from_as_string" : "2020-04-01 00:00:00",
          "to" : 1.588248E12,
          "to_as_string" : "2020-04-30 12:00:00",
          "doc_count" : 3
        },
        {
          "key" : "2020-05-01 00:00:00-2020-05-30 12:00:00",
          "from" : 1.5882912E12,
          "from_as_string" : "2020-05-01 00:00:00",
          "to" : 1.59084E12,
          "to_as_string" : "2020-05-30 12:00:00",
          "doc_count" : 3
        }
      ]
    }
  }

  • histogram
    統(tǒng)計(jì)固定間隔的數(shù)據(jù)數(shù)量。類似一個(gè)樹(shù)形柱狀圖
GET /u/_search
{
    "aggs": {
        "aggs_his": {
            "histogram": {
                "field": "age",
                "interval":5,//統(tǒng)計(jì)年齡間隔5歲的各個(gè)階段的人數(shù)
                "extended_bounds": //查詢范圍
                    {
                        "min":30,
                        "max": 56
                    }
            }
        }
    }
}

返回結(jié)果

 "aggregations": {
        "aggs_his": {
            "buckets": [
                {
                    "key": 25.0,
                    "doc_count": 2
                },
                {
                    "key": 30.0,
                    "doc_count": 6
                },
                {
                    "key": 35.0,
                    "doc_count": 7
                },
                {
                    "key": 40.0,
                    "doc_count": 1
                },
                {
                    "key": 45.0,
                    "doc_count": 0
                },
                {
                    "key": 50.0,
                    "doc_count": 0
                },
                {
                    "key": 55.0,
                    "doc_count": 1
                }
            ]
        }
    }

從query的結(jié)果集中匙头,以ts_m字段指定的范圍蝙叛,取每隔1小時(shí)取一次數(shù)據(jù)量統(tǒng)計(jì)

GET monitor_temp/_search
{
    "query": {
      "range": {
        "ts_m": {
          "gte": 1617273000000,
          "lte": 1617359400000
        }
      }
    },   
    "aggs": {
        "aggs_his": {
            "histogram": {
                "field": "ts_m",
                "format":"yyyy-MM-dd HH:mm",
                "interval":3600000,
                "extended_bounds": 
                    {
                        "max":1617359400000,
                        "min":1617273000000
                    }
            }
        }
    }
}

返回的部分結(jié)果

"aggregations" : {
    "aggs_his" : {
      "buckets" : [
        {
          "key_as_string" : "2021-04-01 10:00",
          "key" : 1.6172712E12,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2021-04-01 11:00",
          "key" : 1.6172748E12,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2021-04-01 12:00",
          "key" : 1.6172784E12,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2021-04-01 13:00",
          "key" : 1.617282E12,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2021-04-01 14:00",
          "key" : 1.6172856E12,
          "doc_count" : 0
        },
        {
          "key_as_string" : "2021-04-01 15:00",
          "key" : 1.6172892E12,
          "doc_count" : 0
        },
      
        .......
      ]
    }
  }
  • date histogram
    用于日期的histogram
GET /u/_search
{
    "aggs": {
        "aggs_his": {
            "date_histogram": {
                "field": "brith",
                "interval":"year",//出生日期以每一年為間隔
                "format": "yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

輸出結(jié)果

"aggregations": {
        "aggs_his": {
            "buckets": [
                {
                    "key_as_string": "1954-01-01 00:00:00",
                    "key": -504921600000,
                    "doc_count": 1
                },
                {
                    "key_as_string": "1959-01-01 00:00:00",
                    "key": -347155200000,
                    "doc_count": 0
                },
                {
                    "key_as_string": "1967-01-01 00:00:00",
                    "key": -94694400000,
                    "doc_count": 0
                },
                {
                    "key_as_string": "1968-01-01 00:00:00",
                    "key": -63158400000,
                    "doc_count": 0
                },
                {
                    "key_as_string": "1969-01-01 00:00:00",
                    "key": -31536000000,
                    "doc_count": 0
                },
              .................

從query的結(jié)果集中展融,以ts_m字段指定的范圍指么,取每隔1小時(shí)取一次數(shù)據(jù)量統(tǒng)計(jì),返回的結(jié)果是上海時(shí)間

GET monitor_temp/_search
{
    "aggregations": {
        "aggs_his": {
            "date_histogram": {
                "extended_bounds": {
                    "max":1617359400000,
                      "min":1617273000000
                },
                "field": "ts_m",
                "interval": "1h",
                "offset": 0,
                "format":"MM-dd HH:mm",
                "order": {
                    "_key": "asc"
                },
                "time_zone": "Asia/Shanghai"
            }
        }
    },
    "query": {
        "range": {
            "ts_m": {
                "from": 1617273000000,
                "to": 1617359400000
            }
        }
    }
}

部分返回結(jié)果

 "aggregations" : {
    "aggs_his" : {
      "buckets" : [
        {
          "key_as_string" : "04-01 18:00",
          "key" : 1617271200000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "04-01 19:00",
          "key" : 1617274800000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "04-01 20:00",
          "key" : 1617278400000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "04-01 21:00",
          "key" : 1617282000000,
          "doc_count" : 0
        },
        {
          "key_as_string" : "04-01 22:00",
          "key" : 1617285600000,
          "doc_count" : 0
        },

Metric

- 單值分析

分析只輸出一個(gè)結(jié)果

  • min酝惧、max、avg伯诬、sum
//查詢age的最小值
GET test/_search
{
  "aggs": {
    "max": {
      "min": {
        "field": "price"
      }
    }
  }
}

輸出部分結(jié)果

"aggregations" : {
    "max" : {
      "value" : 130.0
    }

//查詢age的最大值
GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_name": {
            "max": {
                "field": "age"
            }
        }
    }
}
//查詢age的總值
GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_name": {
            "sum": {
                "field": "age"
            }
        }
    }
}
//查詢age的平均值
GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_name": {
            "avg": {
                "field": "age"
            }
        }
    }
}

可以將他們組合在一起

GET test/_search
{
    "size": 0,
    "aggs": {
        "aggs_avg": {
            "avg": {
                "field": "price"
            }
        },
        "aggs_sum": {
            "sum": {
                "field": "price"
            }
        },
        "aggs_max": {
            "max": {
                "field": "price"
            }
        },
        "aggs_min": {
            "min": {
                "field": "price"
            }
        }
    }
}

輸出部分結(jié)果

"aggregations" : {
    "aggs_sum" : {
      "value" : 134633.0
    },
    "aggs_min" : {
      "value" : 130.0
    },
    "aggs_avg" : {
      "value" : 5853.608695652174
    },
    "aggs_max" : {
      "value" : 22788.0
    }
  }

  • cardinality:統(tǒng)計(jì)某個(gè)字段有多少種類
GET test/_search
{
    "size": 0,
    "aggs": {
        "aggs_cardinality": {
            "cardinality": {
                "field": "productName.keyword" //統(tǒng)計(jì)productName的不同種類
            }
        }
    }
}

部分輸出結(jié)果

"aggregations" : {
    "aggs_cardinality" : {
      "value" : 23
    }
  }

- 多值分析

分析可以輸出多個(gè)結(jié)果

stats晚唇、extended_stats、percentiles:
  • stats:返回一系列統(tǒng)計(jì)類型盗似,包括min,max,avg,sum,count
GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_stats": {
            "stats": {
                "field": "age"
            }
        }
    }
}

輸出的結(jié)果

  "aggregations": {
        "aggs_count": {
            "count": 17,
            "min": 25.0,
            "max": 56.0,
            "avg": 34.64705882352941,
            "sum": 589.0
        }
    }

  • extended_stats:計(jì)算方差哩陕、標(biāo)準(zhǔn)差等使用extended_stats,是對(duì)stats功能的擴(kuò)展
GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_estats": {
            "extended_stats": {
                "field": "age"
            }
        }
    }
}

輸出結(jié)果

    "aggregations": {
        "aggs_estats": {
            "count": 17,
            "min": 25.0,
            "max": 56.0,
            "avg": 34.64705882352941,
            "sum": 589.0,
            "sum_of_squares": 21175.0,
            "variance": 45.16955017301028,
            "std_deviation": 6.720829574763094,
            "std_deviation_bounds": {
                "upper": 48.0887179730556,
                "lower": 21.205399674003225
            }
        }
    }

  • percentiles:統(tǒng)計(jì)數(shù)據(jù)的所占百分位比重,例如統(tǒng)計(jì)數(shù)據(jù)中百分之多少的人是在哪個(gè)年齡段
GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_percentile": {
            "percentiles": {
                "field": "age"
            }
        }
    }
}

返回結(jié)果

   "aggregations": {
       "aggs_percentile": {
           "values": {
               "1.0": 24.999999999999996,//24歲年齡段的有百分之1
               "5.0": 25.0,//25歲年齡段的有百分之5
               "25.0": 31.0,//31歲年齡段的有百分之25
               "50.0": 35.0,//35歲年齡段的有百分之50
               "75.0": 36.0,//36歲年齡段的有百分之75
               "95.0": 50.74999999999998,//51歲年齡段的有百分之95
               "99.0": 56.0//56歲年齡段的有百分之99
           }
       }
}

我們可以指定某個(gè)百分?jǐn)?shù)范圍內(nèi)對(duì)應(yīng)的數(shù)值是哪些

GET /u/_search
{
    "size": 0,
    "aggs": {
        "aggs_percentile": {
            "percentiles": {
                "field": "age",
                "percents":[50,75]
            }
        }
    }
}

返回結(jié)果

 "aggregations": {
        "aggs_percentile": {
            "values": {
                "50.0": 35.0,
                "75.0": 36.0
            }
        }
    }

  • aggs_percentile:我們查某些數(shù)據(jù)范圍中是處于哪個(gè)百分位
GET test/_search
{
  "aggs": {
    "p_r": {
      "percentile_ranks": {
        "field": "price",
        "values": [
          19988,
          5800
        ]
      }
    }
  }
}

輸出結(jié)果

 "aggregations" : {
    "p_r" : {
      "values" : {
        "5800.0" : 63.47826086956522,
        "19988.0" : 94.54434671825976
      }
    }
  }

  • top_hits:我們希望能從分組統(tǒng)計(jì)的基礎(chǔ)上再獲取統(tǒng)計(jì)信息

下面是按照職業(yè)進(jìn)行分組赫舒,但是我們要取每個(gè)分組中前十名

GET /u/_search
{
    "size": 0,
    "aggs": {
        "tj": {
            "terms": {
                "field": "job.keyword"
            },
            "aggs": {
                "my_top": {
                    "top_hits": {
                        "size": 10,
                        "sort": [
                            {
                                "age": {
                                    "order": "desc"
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
}
  • 桶中桶 bucket+Metric的組合拳

在分組后悍及,對(duì)每個(gè)組在進(jìn)行統(tǒng)計(jì)

GET /u/_search
//統(tǒng)計(jì)在職業(yè)分組后,再統(tǒng)計(jì)每組職業(yè)的年齡段占比多少
{
    "aggs": {
        "aggs_term": {
            "terms": {
                "field": "job.keyword",
                "size": 10
            },
            "aggs": {
                "aggs_percentile": {
                    "percentiles": {
                        "field": "age"
                    }
                }
            }
        }
    }
}

返回結(jié)果

"aggregations": {
        "aggs_term": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 2,
            "buckets": [
                {
                    "key": "act",
                    "doc_count": 2,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 36.0,
                            "5.0": 36.0,
                            "25.0": 36.0,
                            "50.0": 38.5,
                            "75.0": 41.0,
                            "95.0": 41.0,
                            "99.0": 41.0
                        }
                    }
                },
                {
                    "key": "act av",
                    "doc_count": 2,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 25.0,
                            "5.0": 25.0,
                            "25.0": 25.0,
                            "50.0": 30.0,
                            "75.0": 35.0,
                            "95.0": 35.0,
                            "99.0": 35.0
                        }
                    }
                },
                {
                    "key": "basketball",
                    "doc_count": 2,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 30.999999999999996,
                            "5.0": 31.0,
                            "25.0": 31.0,
                            "50.0": 31.5,
                            "75.0": 32.0,
                            "95.0": 32.0,
                            "99.0": 32.0
                        }
                    }
                },
                {
                    "key": "basketball mvp",
                    "doc_count": 2,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 29.999999999999996,
                            "5.0": 30.0,
                            "25.0": 30.0,
                            "50.0": 31.0,
                            "75.0": 32.0,
                            "95.0": 32.0,
                            "99.0": 32.0
                        }
                    }
                },
                {
                    "key": "basketball mvp act",
                    "doc_count": 2,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 30.999999999999996,
                            "5.0": 31.0,
                            "25.0": 31.0,
                            "50.0": 43.5,
                            "75.0": 56.0,
                            "95.0": 56.0,
                            "99.0": 56.0
                        }
                    }
                },
                {
                    "key": "basketball act",
                    "doc_count": 1,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 33.0,
                            "5.0": 33.0,
                            "25.0": 33.0,
                            "50.0": 33.0,
                            "75.0": 33.0,
                            "95.0": 33.0,
                            "99.0": 33.0
                        }
                    }
                },
                {
                    "key": "cartoonman hai",
                    "doc_count": 1,
                    "aggs_percentile": {
                        "values": {
                            "1.0": 36.0,
                            "5.0": 36.0,
                            "25.0": 36.0,
                            "50.0": 36.0,
                            "75.0": 36.0,
                            "95.0": 36.0,
                            "99.0": 36.0
                        }
                    }
                }, 
            .............
            ]
        }
  • Pipeline管道聚合分析

針對(duì)上層分析的結(jié)果進(jìn)行再次分析接癌,其分析的結(jié)果會(huì)輸出到上層的結(jié)果中心赶,根據(jù)輸出的位置不同分為兩類:

  • 內(nèi)嵌到上層的結(jié)果中
    min、max扔涧、avg园担、stats、percentiles
    min_bucket\max_bucket\avg_bucket\stats_bucket\percentiles_bucket
    用法差不多枯夜,舉一個(gè)例子弯汰,
//計(jì)算每一類職業(yè)的平均收入,然后找出平均收入最低的職業(yè)
GET /u/_search
{
    "aggs": {
        "aggs_term": {
            "terms": {
                "field": "job.keyword"
            },
            "aggs": {
                "aggs_avg": {
                    "avg": {
                        "field": "income"
                    }
                }
            }
        },
        "min_pipeline": {//給pipeline起名字湖雹,pipeline與aggs的子項(xiàng)aggs_term同級(jí),導(dǎo)致后面的buckets_path要寫(xiě)成aggs_term>aggs_avg
//分析誰(shuí)就與誰(shuí)同級(jí)
            "min_bucket": {//min_bucket是關(guān)鍵詞咏闪,如果是算最大值換成max_bucket,平均值換成avg_bucket、同時(shí)獲取多個(gè)指標(biāo)則用stats_bucket
                "buckets_path": "aggs_term>aggs_avg"http://aggs的所屬結(jié)構(gòu)
            }
        }
    }
}

輸出結(jié)果

  "min_pipeline": {
            "value": 1000.0,//平均收入最低是1000
            "keys": [//這幾個(gè)職業(yè)都是收入最低的
                "cartoonman hai",
                "cartoonman hot",
                "cartoonman qun",
                "cartoonman seven"
            ]
        }
  • 結(jié)果與上層的結(jié)果同級(jí)

  • 聚合分析的范圍

aggs與query關(guān)鍵字同級(jí)摔吏,在query執(zhí)行后鸽嫂,aggs針對(duì)query執(zhí)行的結(jié)果進(jìn)行分析,也就是說(shuō)query查出來(lái)結(jié)果就是aggs的分析范圍
也可以在aggs內(nèi)部使用filter關(guān)鍵詞限定范圍

GET /u/_search
{
    "aggs": {
        "aggs_filter": {
            "filter": {//利用filter限定aggs范圍
                "match": {
                    "job":"basketball"
                }
            },
            "aggs":{
                "job_aggs":{
                    "terms":{
                        "field":"job.keyword"
                    }
                }
            }
        }
       
    }
}

還要一種限定范圍的方法是post_filter在aggs分析之后在進(jìn)行篩選

{
    "aggs": {
        "job_aggs": {
            "terms": {
                "field": "job.keyword"
            }
        }
    },
    "post_filter":{
        "match":{
            "job.keyword":"mvp"
        }
    }
}

聚合排序sort

GET /u/_search
{
    "aggs": {
        "aggs_term": {
            "terms": {
                "field": "job.keyword",
                 "order":{
                    "aggs_avg":"desc"http://以子聚合分析的結(jié)果排序
                }  
            },
            "aggs": {
                "aggs_avg": {
                    "avg": {
                        "field": "income"
                    }
                }
            }
            
        }
       
    }
}

返回結(jié)果

 "buckets": [
                {
                    "key": "soccerball mvp",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 5.0E8
                    }
                },
                {
                    "key": "basketball mvp",
                    "doc_count": 2,
                    "aggs_avg": {
                        "value": 1.3E8
                    }
                },
                {
                    "key": "basketball",
                    "doc_count": 2,
                    "aggs_avg": {
                        "value": 8.5E7
                    }
                },
                {
                    "key": "act",
                    "doc_count": 2,
                    "aggs_avg": {
                        "value": 1.01E7
                    }
                },
                {
                    "key": "basketball mvp act",
                    "doc_count": 2,
                    "aggs_avg": {
                        "value": 750000.0
                    }
                },
                {
                    "key": "basketball act",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 600000.0
                    }
                },
                {
                    "key": "act av",
                    "doc_count": 2,
                    "aggs_avg": {
                        "value": 40000.0
                    }
                },
                {
                    "key": "great",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 8000.0
                    }
                },
                  .........................

以外層的key或者聚合分析數(shù)排序

GET /u/_search
{
    "aggs": {
        "aggs_term": {
            "terms": {
                "field": "job.keyword",
                "order": [
                    {
                        "_key": "desc"http://聚合結(jié)果的key排序
                    },
                    {
                        "_count": "desc"http://聚合數(shù)量排序
                    }
                ]
            },
            "aggs": {
                "aggs_avg": {
                    "avg": {
                        "field": "income"
                    }
                }
            }   
        }  
    }
}

返回結(jié)果

"buckets": [
                {
                    "key": "soccerball mvp",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 5.0E8
                    }
                },
                {
                    "key": "great",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 8000.0
                    }
                },
                {
                    "key": "cartoonman seven",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 1000.0
                    }
                },
                {
                    "key": "cartoonman qun",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 1000.0
                    }
                },
                {
                    "key": "cartoonman hot",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 1000.0
                    }
                },
                {
                    "key": "cartoonman hai",
                    "doc_count": 1,
                    "aggs_avg": {
                        "value": 1000.0
                    }
                },
                  ..........................
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末征讲,一起剝皮案震驚了整個(gè)濱河市据某,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诗箍,老刑警劉巖癣籽,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異滤祖,居然都是意外死亡筷狼,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)匠童,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)埂材,“玉大人,你說(shuō)我怎么就攤上這事汤求∏蜗眨” “怎么了严拒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)竖独。 經(jīng)常有香客問(wèn)我糙俗,道長(zhǎng),這世上最難降的妖魔是什么预鬓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮赊颠,結(jié)果婚禮上格二,老公的妹妹穿的比我還像新娘。我一直安慰自己竣蹦,他們只是感情好顶猜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著痘括,像睡著了一般长窄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纲菌,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天挠日,我揣著相機(jī)與錄音,去河邊找鬼翰舌。 笑死嚣潜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的椅贱。 我是一名探鬼主播懂算,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼庇麦!你這毒婦竟也來(lái)了计技?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤山橄,失蹤者是張志新(化名)和其女友劉穎垮媒,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驾胆,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涣澡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丧诺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片入桂。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖驳阎,靈堂內(nèi)的尸體忽然破棺而出抗愁,到底是詐尸還是另有隱情馁蒂,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布蜘腌,位于F島的核電站沫屡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏撮珠。R本人自食惡果不足惜沮脖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芯急。 院中可真熱鬧勺届,春花似錦、人聲如沸娶耍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)榕酒。三九已至胚膊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間想鹰,已是汗流浹背紊婉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杖挣,地道東北人肩榕。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像惩妇,于是被迫代替她去往敵國(guó)和親株汉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354