GET /customer/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
},0
"aggs": {
"group_by_gender": {
"terms": {
"field": "gender.keyword"
},
"aggs": {
"avg_pri": {
"avg": {
"field": "balance"
}
}
}
}
}
},
"avg_balance":{
"avg": {
"field": "balance"
}
}
}
}
GET /customer/_search?size=0
{
"aggs": {
"avg_grade": {
"avg": {
"field": "balance"
}
}
}
}
GET /customer/_search?size=0
{
"aggs": {
"avg_grade": {
"avg": {
"script": {
"source": "doc.balance.value"
}
}
}
}
}
POST /customer/_search?size=0
{
"aggs" : {
"avg_corrected_grade" : {
"avg" : {
"field" : "balance",
"script" : {
"lang": "painless",
"source": "_value * params.correction",
"params" : {
"correction" : 1
}
}
}
}
}
}
自定義分詞器
# 指定analyer進行分詞校驗
POST _analyze
{
"analyzer": "ik_smart",
"text": "這里是江西的師范大學(xué)"
}
# 指定字段進行校驗赞警,得出檢索不出預(yù)期結(jié)果的原因
POST /test_index/_analyze
{
"field": "name",
"text": "Hello world"
}
# 指定char_filter和tokenizer
POST _analyze
{
"tokenizer": "keyword",
"char_filter": [
"html_strip"
],
"text": "<p>Hello World</p>"
}
# 在創(chuàng)建index時指定analyer
PUT test_index_1
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyer": {
"type": "custom",
"char_filter": [
"html_strip"
],
"tokenizer": "standard",
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
}
}
# 自定義分詞器
PUT test_index_2
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyer": {
"type": "custom",
"char_filter": [
"emoticons"
],
"tokenizer": "punctuation",
"filter": [
"lowercase",
"english_stop"
]
}
},
"tokenizer": {
"punctuation": {
"type": "pattern",
"pattern": "[.,!?]"
}
},
"char_filter": {
"emoticons": {
"type": "mapping",
"mappings": [
":> => happy",
":< => sad",
"cat => yjn"
]
}
},
"filter": {
"english_stop": {
"type": "stop",
"stopwords": "_english_"
}
}
}
}
}
POST test_index_2/_analyze
{
"analyzer":"my_custom_analyer",
"text": "cat.cat.cat"
}
PUT test_analyze
{
"settings": {
"analysis": {
"analyzer": {
"pinyin_test": {
"char_filter": [
"html_strip",
"mymap",
"mypattern"
],
"tokenizer": "test_tokenizer"
}
},
"tokenizer": {
"test_tokenizer": {
"type": "keyword"
}
},
"char_filter": {
"mymap": {
"type": "mapping",
"mappings": [
"* => 我",
"# => 愛",
"^ => 你"
]
},
"mypattern": {
"type": "pattern_replace",
"pattern": "\\s+",
"replacement": ""
}
}
}
}
}
GET test_analyze/_analyze
{
"text": "<p>fkj<br>s<ajf>*ld#fk^^d</p>",
"analyzer": "pinyin_test"
}
自定義Mapping
PUT test_index_3
{
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "keyword"
},
"sex" : {
"type" : "boolean"
}
}
}
}
GET /test_index_3/_mapping
自定義mapping和dynamic對新增字段的意義
dynamic值 | 結(jié)果 |
---|---|
false | 可以正常插入新字段數(shù)據(jù)找前,但是不會創(chuàng)建新字段 |
true | 可以正常插入新字段數(shù)據(jù)诀豁,會創(chuàng)建新字段 |
"strict" | 插入新的字段會報錯 |
PUT my_index
{
"mappings" : {
"dynamic": true,
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "keyword"
},
"sex" : {
"type" : "boolean"
}
}
}
}
GET my_index/_mapping
PUT my_index/_doc/1
{
"name": "zjb",
"title": "yjn"
}
GET my_index/_search
DELETE my_index
自定義mapping之index胎源,字段能否被檢索
PUT my_index
{
"mappings": {
"properties": {
"cookie": {
"type": "text",
"index": false
}
}
}
}
PUT my_index/_doc/1
{
"cookie": "name=zjb"
}
GET my_index/_search
{
"query": {
"match": {
"cookie": "TEXT"
}
}
}
自定義mapping之copy_to
DELETE my_index
PUT my_index
{
"mappings": {
"properties": {
"first_name":{
"type": "text",
"copy_to": "full_name"
},
"last_name":{
"type":"text",
"copy_to": "full_name"
},
"full_name":{
"type": "text"
}
}
}
}
POST my_index/_doc/1
{
"first_name":"zhan",
"last_name":"jinbing"
}
GET my_index/_search
{
"query": {
"match":{
"full_name": {
"query":"zhan jinbing",
"operator": "or"
}
}
}
}
自定義Mapping--index_options
- index_options 用于控制倒排索引記錄的內(nèi)容鲫寄,有如下4中配置
- docs只記錄 doc id
- freqs 記錄doc id 和 term frequencies
- positions 記錄 doc id、term frequencies和term position
- offsets 記錄 doc id疯汁、term frequencies牲尺、term position 和character offsets
- text類型默認配置 positions,其他默認為 docs
- 記錄內(nèi)容越多,占用空間越大
自定義Mapping--null_value
- 當(dāng)字段遇到null值的處理策略幌蚊,默認為null谤碳,即空值凛澎,此時es會忽略該值」捞悖可以通過設(shè)定該值設(shè)定字段的默認值
PUT my_index
{
"mappings": {
"properties": {
"first_name":{
"type": "text",
"null_value": "這是默認值"
}
}
}
}
自定義mapping--數(shù)據(jù)類型
多字段特性 multi-fields
- 允許對同一個字段采用不同的配置,比如分詞沫换,常見例子如對人名實現(xiàn)拼音搜索臭蚁,只需要在人名中新增一個子字段為pinyin即可
PUT my_index
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"pinyin": {
"type": "text",
"analyzer": "pinyin"
}
}
}
}
}
}
# 檢索方式
GET test_index/_search
{
"query": {
"match": {
"username.pinyin": "hanhan"
}
}
}
# 配置多個附屬字段方便查詢
PUT test_index
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"py_name": {
"type": "text",
"analyzer": "pinyin"
},
"ik_name": {
"type": "text",
"analyzer": "ik_smart"
},
"smartcn_name": {
"type": "text",
"analyzer": "smartcn"
}
},
"analyzer": "keyword"
}
}
}
}
這里要注意分詞器
analyzer
是要具有將文字轉(zhuǎn)拼音
的功能的
自定義mapping之通過numeric_detection開啟字符串?dāng)?shù)值探測和dynamic_date_formats設(shè)置日期格式
Query
URI Search
- 通過url query參數(shù)來實現(xiàn)搜索,常用參數(shù)如下:
- q指定查詢的語句讯赏,語法為Query String Syntax
- df q 中不指定字段時默認查詢的字段垮兑,如果不指定,es會查詢所有字段
- sort 排序
- timeout 指定超時時間漱挎,默認不超時
- from系枪,size用于分頁
GET /my_index/_search?q=alfred&df=user&sort=age:asc&from=4&size=10&timeout=1s
查詢user字段包含alfred的文檔,結(jié)果按照age升序排序磕谅,返回第5個-到第14個文檔私爷,如果超過1s沒有結(jié)束,則超時結(jié)束
布爾操作符
- AND(&&) 膊夹,OR(||) 衬浑,NOT(!)
- name:(tom NOT lee)
查詢name中有tom但是沒有l(wèi)ee
- 注意大寫,不能小寫
- name:(tom NOT lee)
-
+ -
分別對應(yīng) must 和 must_not- name: (tom +lee -alfred )
- name: ((lee && !alfred) || (tom && lee && !alfred))
-
+
在 url中會被解析為空格放刨,要使用encode后的結(jié)果才可以工秩,為%2B
范圍查詢,支持數(shù)值和日期
- 區(qū)間寫法进统,閉區(qū)間用[]助币,開區(qū)間用{}
- age: [1 TO 10]意為1<=age<=10
- age: [1 TO 10]意為1<=age<=10
- age:[1 TO ]意為age>=1
- age:[* TO 10]意為age<=10
- 算數(shù)符號寫法
- age: >= 1
- age:(>=1 && <=10)或者 age:(+>=1 +<=10)
- 通配符查詢
- ?代表1個字符螟碎,* 代表0或多個字符
- name: t?m
- name: tom*
- name:t*m
- ?代表1個字符螟碎,* 代表0或多個字符
- 通配符匹配執(zhí)行效率低眉菱,且占用較多內(nèi)存,不建議使用
- 如無特殊需求抚芦,不要將
?/*
放在最前面倍谜,這樣很吃內(nèi)存 - 正則表達式匹配
- name:/[mb]oat/ ===> +name:(moat boat)
- 模糊匹配 fuzzy query
- name: roam ~ 1
- 匹配與roam 差一個 character 的詞,比如foam roams等
- 近似度查詢 proximity search
- "fox quick" ~ 5
- 以term為單位進行差異比較叉抡,比如"quick fox" "quick brown fox"都會被匹配
Query DSL - 字段類查詢
- 全文匹配
- 針對text類型的字段進行全文檢索尔崔,會對查詢語句先進行分詞處理,如match褥民、match_phrase等query類型
- 單詞匹配
-
不會對查詢的語句做分詞處理季春,直接去匹配字段的倒排索引,如term消返、terms载弄,range等query類型
-
fuzziness 模糊一個character耘拇,(可以錯一個,多一個宇攻,少一個)
GET test_index/_search
{
"_source": "name",
"profile": "true",
"query": {
"match": {
"name.py_name":{
"query": "占金兵1",
"analyzer": "keyword",
"fuzziness": 1
}
}
}
}
minimum_should_match至少包含幾個
GET test/_search
{
"query": {
"match": {
"name": {
"query": "zhan jin bing1",
"minimum_should_match": 2
}
}
}
}
相關(guān)性算分
- 相關(guān)性算分的幾個重要概念如下:
- Term Frequency(TF) 詞頻惫叛,即單詞在該文檔中出現(xiàn)的次數(shù)。詞頻越高逞刷,相關(guān)度越高
- Document Frequency(DF)文檔頻率嘉涌,即單詞出現(xiàn)的文檔數(shù)
- Inverse Document Frequency(IDF) 逆向文檔頻率,與文檔頻率相反夸浅,簡單理解為1/DF仑最,即單詞出現(xiàn)的文檔數(shù)越少,相關(guān)度越高
- Field-length Norm 文檔越短帆喇,相關(guān)性越高
document frequency
說明:查詢的詞中有一個詞只在很少的文檔中出現(xiàn)了警医,用戶想得到的結(jié)果很可能在這些少數(shù)的文檔中,所以加大權(quán)重坯钦,相關(guān)性得分高
相關(guān)性算分 - TF/IDF 模型
- 可以通過explain參數(shù)來查看具體的計算方法预皇,但是要注意:
- es的算分是按照shard進行的,即shard的分數(shù)計算是相互獨立的婉刀,所以在使用explain的時候注意分片個數(shù)
- 可以通過設(shè)置索引的分片數(shù)為1來避免這個問題
GET test/_search
{
"explain": true,
"query": {
"match": {
"name": "zhan jin"
}
}
}
match_phrase
通過測試可以發(fā)現(xiàn)
match_phrase
也會對查詢的語句進行分詞處理深啤,在與倒排序單詞匹配的時候有順序要求
match_phrase slop
因為match_phrase查詢有順序要求,缺了一個都不行路星,slop就是一個定義match_phrase可以缺幾個的字段溯街。可以理解slop默認為0
GET test_index/_search
{
"query": {
"match_phrase": {
"name": {
"query": "金兵",
"analyzer": "keyword",
"slop": 1
}
}
}
}
regexp 正則查詢
正則查詢的語句是不會分詞的洋丐,如果查詢的字段是分詞的呈昔,那查詢就會有問題,可以設(shè)置一個子字段不分詞
GET test_index/_search
{
"profile": "true",
"query": {
"regexp": {
"name.py_name": "[憶占](江南|金兵)"
}
}
}
query_string
query_string就是URI方式的q堤尾,df就是default_field,也可以指定fields字段數(shù)組
Simple Query String Query
- 類似Query String,但是會忽略錯誤的查詢語法迁客,并且僅支持部分查詢語法
- 其常用的邏輯符號如下郭宝,不能使用AND、OR掷漱、NOT等關(guān)鍵詞:
-
+
代指 AND -
|
代指OR -
-
代指NOT
-
注意
simple_query_string
容錯性很好
Term和Terms
match會對查詢的語句進行分詞處理粘室,但是有時候我們并不想查詢的詞被分詞處理,這時候就可以使用term和terms了
Range Query - Date Math
range查詢用于
數(shù)值范圍
和日期范圍
的查詢
- 針對日期提供的一種更友好地計算方式卜范,格式如下:
now - 1d
:這里地now
是基準日期衔统,也可以使用具體地日期來當(dāng)作基準,比如2018-01-01
,使用具體日期地時候要用||
做隔離
計算公式锦爵,主要有如下3種舱殿,
+1h
加1個小時
-1d
減1天
/d
將時間舍入到天
可以使用的單位:- y - year - 年
- M - month - 月
- w - week - 周
- d - day - 天
- h - hour - 時
- m - minute - 分
- s - second - 秒
這里舉個例子:防止以后懵逼 = - =
假設(shè)now為 2018-01-02 12:00:00
,那么如下的計算結(jié)果實際為:
計算公式 | 實際結(jié)果 |
---|---|
now+1h | 2018-01-02 13:00:00 |
now-1h | 2018-01-02 11:00:00 |
now-1h/d | 2018-01-02 00:00:00 |
2016-01-01|| +1M/d |
2016-02-01 00:00:00 |
上面的公式不能有空格
GET test/_search
{
"profile": true,
"query": {
"range": {
"age": {
"gte": 25,
"lte": 29
}
}
}
}
GET test/_search
{
"query": {
"range": {
"birth": {
"gte": "01/1990/10||+4y"
}
}
}
}
Query DSL - 復(fù)合查詢
- 復(fù)合查詢是指包含字段類查詢或復(fù)合查詢的類型险掀,主要包括以下幾類:
- constant_score query
- bool query
- dis_max query
- function_score query
- boosting query
Bool Query
- 布爾查詢由一個或多個布爾子句組成沪袭,主要包含如下4個:
子句key | 說明 |
---|---|
filter | 只過濾符合條件的文檔,不計算相關(guān)性得分 |
must | 文檔必須符合must中的所有條件樟氢,會影響相關(guān)性得分 |
must_not | 文檔必須不符合must_not中的所有條件 |
should | 文檔可以符合should中的條件枝恋,會影響相關(guān)性得分 |
GET test/_search
{
"query": {
"bool": {
"filter": {
"term": {
"name": "zhan"
}
}
}
}
}
GET test/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "zjb"
}
},
{
"match": {
"age": 22
}
}
]
}
}
}
GET test/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "zjb"
}
},
{
"match": {
"age": 22
}
}
]
}
}
}
GET test/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "zjb"
}
},
{
"match": {
"age": 22
}
}
]
}
}
}
注意:當(dāng)只有
should
子句沒有must
子句時,should
子句是必須至少要匹配一個條件的document
才會返回嗡害,當(dāng)有must
子句時,只要滿足了must
的條件就會返回畦攘,should
子句中的條件可以不必滿足霸妹,滿不滿足只是對相關(guān)性得分有影響
Query Context VS Filter Context
- 當(dāng)一個查詢語句于Query或者Filter上下文時,es執(zhí)行的結(jié)果會不同知押,對比如下:
上下文類型 | 執(zhí)行類型 | 使用方式 |
---|---|---|
Query | 查找與查詢語句最匹配的文檔叹螟,對所有文檔進行相關(guān)性算分并排序 | * query * bool中的must和should |
Filter | 查詢與查詢語句相匹配的文檔 | * bool 中的 filter 與 must_not * constant_score 中的filter |
查詢匹配的數(shù)量count
GET test/_count
{
"query": {
"match_all": {
}
}
}
指定返回的source
GET test/_search
{
"_source": false,
"query": {
"match_all": {}
}
}
GET test/_search
{
"_source": "name",
"query": {
"match_all": {}
}
}
GET test/_search
{
"_source": ["name","age"],
"query": {
"match_all": {}
}
}
GET test/_search
{
"_source": {
"includes": "n*"
},
"query": {
"match_all": {}
}
}
GET test/_search
{
"_source": {
"includes": "n*",
"excludes": "name"
},
"query": {
"match_all": {}
}
}
分布式特性
- es支持集群模式,是一個分布式系統(tǒng)台盯,其好處主要有兩個:
- 增大系統(tǒng)容量罢绽,如內(nèi)存、磁盤静盅、使得es集群可以支持PB級的數(shù)據(jù)
- 提高系統(tǒng)可用性良价,即使部分節(jié)點停止服務(wù),整個集群依然可以正常服務(wù)
- es集群由多個es實例組成
- 不同集群通過集群名字來區(qū)分蒿叠,可通過cluster.name進行修改明垢,默認為elasticsearch
- 每個es實例本質(zhì)上是一個JVM進程,且有自己的名字市咽,通過node.name進行修改
安裝
cerebro
進行可視化集群狀態(tài)監(jiān)控
啟動一個節(jié)點
- 運行如下命令可以啟動一個es節(jié)點實例
bin/elasticsearch -E cluster.name=集群名 -E node.name=節(jié)點名
不同的node需要不同的數(shù)據(jù)目錄和端口痊银,如果在同一臺機器上部署多個實例,啟動節(jié)點時可以使用
-Epath.data=數(shù)據(jù)目錄 -Ehttp.port=端口
PUT /stconvert/
{
"settings": {
"analysis": {
"analyzer": {
"tsconvert": {
"tokenizer": "tsconvert"
}
},
"char_filter": {
"tsconvert": {
"type": "stconvert",
"convert_type": "t2s"
}
},
"tokenizer": {
"tsconvert": {
"type": "stconvert",
"delimiter": "#",
"keep_both": false,
"convert_type": "t2s"
}
},
"filter": {
"tsconvert": {
"type": "stconvert",
"delimiter": "#",
"keep_both": false,
"convert_type": "t2s"
}
}
}
}
}
GET stconvert/_analyze
{
"tokenizer": "keyword",
"filter": [
"lowercase"
],
"char_filter": [
"tsconvert"
],
"text": "擴大寄生蜂離開的"
}
Fielddata vs DocValues
對比 | FieldData | DocValues |
---|---|---|
創(chuàng)建時機 | 搜索時即時創(chuàng)建 | 索引 時創(chuàng)建施绎,與倒排索引創(chuàng)建時機一致 |
創(chuàng)建位置 | JVM Heap | 磁盤 |
優(yōu)點 | 不會占用額外的磁盤空間 | 不會占用Heap內(nèi)存 |
缺點 | 文檔過多時溯革,即時創(chuàng)建會花過多時間,占用過多的Heap內(nèi)存 | 減慢索引的速度谷醉,占用額外的磁盤資源 |
GET _analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "stop",
"ignore_case": true,
"stopwords": [
"這",
"個",
"一",
"是"
]
},
{
"type": "synonym",
"lenient": true,
"expand": true,
"synonyms": [
"占金兵 => 易江南"
]
}
],
"text": "這 是 一 個 占金兵"
}