PUT /test_index
PUT /test_index/doc/1 { "username":"alfred", "age":1 }
建立文檔時,若是索引不存在,es會自動建立對應的index和typehtml
POST /test_index/doc { "username":"tom", "age":20 }
GET /test_index/doc/1
GET /test_index/doc/_search { "query":{ "term":{ "_id":"1" } } }
查詢語句,json格式,放在http body中發送到esjava
POST _bulk {"index":{"_index":"test_index","_type":"doc","_id":"3"}} {"username":"alfred","age":10} {"delete":{"_index":"test_index","_type":"doc","_id":"1"}}
GET /_mget { "doc":[ { "_index":"test_index", "_type":"doc", "_id":"1" }, { "_index":"test_index", "_type":"doc", "_id":"2" } ] }
文檔id | 文檔內容 |
---|---|
1 | elasticsearch是最流行的搜索引擎 |
2 | PHP是世界上最好的語言 |
3 | 搜索引擎是如何誕生的 |
單詞 | 文檔ID列表 |
---|---|
elasticsearch | 1 |
流行 | 1 |
搜索引擎 | 1,3 |
世界 | 2 |
POST _analyze { "analyzer":"standard", #分詞器 "text":"hello,world" #測試文本 }
POST _analyze { "tokenizer":"standard", "filterf":["lowercase"], #自定義analyzer "text":"hello world" }
POST _analyze { "tokenizer":"keyword", #keyword類型的Tokenizer能夠直接看到輸出結果 "char_filter":["html_strip"], #指明要使用的char_filter "text":"<p>I'm so <b>happy</b>!</p>" }
POST _analyze { "tokenizer":"path_hierarchy", "text":"/one/two/three" }
POST _analyze { "text":"a hello world", "tokenizer":"standard", "filter":[ "stop", "lowercase", { "type":"ngram", "min_gram":4, "max_gram":4 } ] }
PUT test_index { "settings":{ "analysis":{ "char_filter":{}, "tokenizer":{}, "filter":{}, "analyzer":{} } } }
PUT test_index { "mappings":{ "doc":{ "properties":{ "title":{ "type":"text", "analyzer":"whitespace" #指定分詞器 } } } } }
查詢時分詞的指定方式有以下幾種:node
POST test_index/_search { "query":{ "match":{ "message":{ "query":"hello", "analyzer":"standard" } } } }
PUT test_index { "mappings":{ "doc":{ "properties":{ "title":{ "type":"text", "analyzer":"whitespace", "search_analyzer":"standard" } } } } }
PUT my_index { "mappings":{ "doc":{ "properties":{ "title":{ "type":"text" }, "name":{ "type":"keyword" }, "age":{ "type":"integer" } } } } }
PUT my_index { "mappings":{ "doc":{ "properties":{ "first_name":{ "type":""text", "copy_to":"full_name" }, "last_name":{ "type":"text", "copy_to":"full_name" }, "full_name":{ "type":"text" } } } } }
PUT my_index { "mappings":{ "doc":{ "properties":{ "cookie":{ "type":"text", "index":"false" } } } } }
PUT my_index { "mappings":{ "doc":{ "properties":{ "cookies":{ "type":"text", "index_options":"offsets" } } } } }
PUT my_index { "mappings":{ "my_type":{ "properties":{ "status_code":{ "type":"keyword", "null_value":"NULL" } } } } }
{ "test_index":{ "mappings":{ "doc":{ "properties":{ "username":{ "type":"text", "fields":{ "pinyin":{ "type":"text", "analyzer":"pinyin" } } } } } } } }
JSON類型 | es類型 |
---|---|
null | 忽略 |
Boolean | Boolean |
浮點類型 | float |
整數 | long |
object | object |
array | 有第一個非null值的類型決定 |
string | 匹配爲日期則設爲date類型(默認開啓),匹配爲數字的話設爲float或long類型(默認關閉),設爲text類型,並附帶keyword的子字段 |
PUT mu_index { "mappings":{ "my_type":{ "dynamic_date_formats":["MM/dd/yyyy"], "date_detection":false } } }
PUT my_index { "mappings":{ "my_type":{ "numeric_detection":true } } }
PUT test_index { "mappings":{ "doc":{ "dynamic_templates":[#數組,可指定多個匹配規則 { "strings":{ #模板名稱 "match_mapping_type":"string",#匹配規則 "mapping":{ "type":"keyword" } } } ] } } }
首先建立一個文檔python
PUT my_index/doc/1 { "referrer": "-", "response":"200", "remote_ip":"171.22.12.14", "method":"POST", "user_name":"-", "http_version":"1.1", "body_sent":{ "bytes":"0" }, "url":"/analyzeVideo" }
es會根據建立的文檔動態生成映射,能夠直接將動態生成的映射直接複製到須要自定義的mapping中nginx
PUT test_index { "mappings": { "doc": { "properties": { "body_sent": { "properties": { "bytes": { "type": "long" } } }, "http_version": { "type": "keyword" }, "method": { "type": "keyword" }, "referrer": { "type": "keyword" }, "remote_ip": { "type": "keyword" }, "response": { "type": "long" }, "url": { "type": "text" }, "user_name": { "type": "keyword" } } } } }
這樣定義的映射仍是比較多餘,能夠利用動態模板將string類型直接替換成keywordgit
DELETE test_index PUT test_index { "mappings": { "doc": { "dynamic_templates":[ { "strings":{ "match_mapping_type":"string", "mapping":{ "type":"keyword" } } } ], "properties": { "body_sent": { "properties": { "bytes": { "type": "long" } } }, "response": { "type": "long" }, "url": { "type": "text" } } } } }
索引模板API以下所示:github
PUT _template/test_template { "index_patterns":["te*","bar*"], "order":0, "settings":{ "number_of_shards":1, "number_of_replicas":0 }, "mappings":{ "doc":{ "_source":{ "enabled":false }, "properties":{ "name":{ "type":"keyword" } } } } }
GET test_index/_search { "query":{ "match":{ #關鍵詞 "remote_ip":"171.22.12.14" #字段名 } } }
響應結果以下:正則表達式
{ "took": 4, #查詢總用時 "timed_out": false, #是否超時 "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, #匹配文檔總數 "max_score": 0.2876821, "hits": [ #返回文檔列表 { "_index": "test_index_index", "_type": "doc", "_id": "1", "_score": 0.2876821, #文檔相關度得分 "_source": { #文檔原始內容 "referrer": "-", "response": "200", "remote_ip": "171.22.12.14", "method": "POST", "user_name": "-", "http_version": "1.1", "body_sent": { "bytes": "0" }, "url": "/analyzeVideo" } } ] } }
首先對查詢語句進行分詞,分詞後分別根據字段的倒排索引進行匹配算分,並會匹配到一個或多個文檔,再將匹配到的文檔進行彙總得分,根據得分排序返回多個文檔算法
GET test_index_index/_search { "query":{ "match_phrase":{ "remote_ip":"171.22.12.14" } } }
相似於URI Search中的q參數查詢sql
GET test_index_index/_search { "query":{ "query_string":{ "default_field":"remote_ip", "query":"171.22.12.14" } } }
其經常使用的邏輯符號以下,不能使用AND、OR、NOT等關鍵詞:
GET test_index_index/_search {
"query":{
"simple_query_string":{
"fields":["remote_ip"],
"query":"alfred +way"
}
}
}
將查詢語句做爲整個單詞進行查詢,即不對查詢語句作分詞處理,以下所示:
GET test_index_index/_search { "query":{ "term":{ "remote_ip":"171.22.12.14" } } }
範圍查詢主要針對數值和日期類型,以下所示:
GET test_index_index/_search { "query":{ "range":{ "response":{#找出響應狀態碼大於10,小於300的文檔 "gt": 10, "lte":300 } } } }
針對日期的查詢以下所示:
GET test_index_index/_search { "query":{ "range":{ "birth":{ "gt": "1990-01-01", "lte":"now-2h", "gt":"2019-01-01||+1M/d" } } } }
相關性算分的幾個重要概念以下:
GET test_index_index/_search { "explain": true, "query":{ "match":{ "remote_ip":"171.22.12.14" } } }
GET test_index_index/_search { "query":{ "constant_score":{ "filter":{ "match": { "response":200 } } } } }
響應以下:
{ "took": 7, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "test_index_index", "_type": "doc", "_id": "1", "_score": 1, "_source": { "referrer": "-", "response": "200", "remote_ip": "171.22.12.14", "method": "POST", "user_name": "-", "http_version": "1.1", "body_sent": { "bytes": "0" }, "url": "/analyzeVideo" } } ] } }
子句 | 內容 |
---|---|
filter | 只過濾符合條件的文檔,不計算相關性得分 |
must | 文檔必須符合must中的全部條件,會影響相關性得分 |
must_not | 文檔必須不符合must_not中的全部條件 |
should | 文檔能夠符合should中的條件,會影響相關性得分 |
GET test_index_index/_search { "query":{ "bool":{ "filter":[ {} ], "should":[ {} ], "must":[ {} ], "must_not": [ {} ] } } }
查詢response爲200,ip爲"171.22.12.14"的值
GET test_index_index/_search { "query":{ "bool":{ "must":[ { "match":{ "response":200 } }, { "match":{ "remote_ip": "171.22.12.14" } } ] } } }
上下文類型 | 執行類型 | 使用方式 |
---|---|---|
Query | 查詢與查詢語句最匹配的文檔,對全部文檔進行相關性算分並排序 | 1.query 2. bool中的must和should |
Filter | 查找與查詢語句相匹配的文檔,只過濾不算分,常用過濾器,ES會自動的緩存過濾器的內容,這對於查詢來講,會提升不少性能 | 1.bool中的filter與must_not 2.constant_score中的filter |
GET /_search { "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }
GET test_index_index/_count { "query":{ "match":{ "response":200 } } }
響應以下:
{ "count": 1, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 } }
GET test_index/_search { "_source":false }
返回部分字段
GET test_index/_search { "_source":["response","name"] } GET test_index/_search { "_source":{ "includes":"*i*", "excludes":"remote_ip" } }
GET test_index/_search?search_type=dfs_query_then_fetch
GET test_search_index/_search { "sort":[ #關鍵字 { "birth":"desc" }, { "_score":"desc" }, { "_doc":"desc" } ] }
GET test_search_index/_search { "sort":{ "username":"desc" } } #會產生報錯
GET test_search_index/_search { "sort":{ "username.keyword":"desc" } }
文檔ID | 字段值 |
---|---|
1 | 100 |
2 | 89 |
3 | 129 |
對比 | fielddata | DocValues |
---|---|---|
建立時機 | 搜索時即時建立 | 索引時建立,與倒排索引建立時機一致 |
建立位置 | JVM Heap | 磁盤 |
優勢 | 不會佔用額外的磁盤空間 | 不會佔用Heap內存 |
缺點 | 文檔過多時,即時建立會花過多時間,佔用過多Heap內存 | 減慢索引的速度,佔用額外的磁盤資源 |
PUT test_search_index/_mapping/doc { "properties":{ "username":{ "type":"text", "fileddata":"true" } } }
PUT test_doc_value/ { "mappings":{ "doc":{ "properties": } } }
GET test_search_index/_search { "docvalue_fields":[ "username", "username.keyword", "age" ] }
total_page=(total+page_size-1)/page_size total爲文檔總數
GET test_search_index/_search?scrol=5m #該scroll快照有效時間 { "size":1 #指明每次scroll返回的文檔數 }
post _search/scroll { "scroll":"5m", #指明有效時間 "scroll_id":"..." #上一步返回的id }
DELETE /_search/scroll { "scroll_id":[ "DXFZAD....", "DESGRHRH..." ] } DELETE /_search/scroll/_all
GET test_search_index/_search { "size":1, "sort":{ "age":"desc", "_id":"desc" } } GET test_search_index/_search { "size":1, "search_after":[28,"2"], "sort":{ "age":"desc", "_id":"desc" } }
類型 | 場景 |
---|---|
from/size | 須要實時獲取頂部的部分文檔,且須要自由翻頁 |
scroll | 須要所有文檔,如導出全部數據的功能 |
search_after | 須要所有文檔,不須要自由翻頁 |
GET test_search_index/_search { "size":0, "aggs":{ #關鍵詞,與query同級 "<aggregation_name>":{#定義聚合名稱 "<aggregation_type>":{#定義聚合類型 <aggregation_body> }, [,"aggs":{[<sub_aggregation>]+}]? #子查詢 } [,"<aggregation_name_2>":{...}]* #能夠包含多個聚合分析 } }
GET test_search_index/_search { "size":0, #不須要返回文檔列表 "aggs":{ "min_age":{ "min":{ #關鍵詞 "field":"age" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "max_age":{ "max":{ "field":"age" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "count_of_job":{ "cardinality":{ #關鍵詞 "field":"job.keyword" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "stats_age":{ "stats":{ "field":"age" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "stats_age":{ "extended_status":{ "field":"age" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "per_age":{ "percentiles":{ #關鍵詞 "field":"salary" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":10 }, "aggs":{ "top_employee":{ "top_hits":{ "size":10, "sort":[ { "age":{ "order":"desc" } } ] } } } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ #關鍵詞 "field":"job.keyword",#指明term字段 "size":5 #指定返回數目 } } } }
GET test_search_index/_search { "size":0, "aggs":{ "salary_range":{ "range":{ #關鍵詞 "field":"salary",\ "ranges":[ #指定每一個range的範圍 { "to":1000 }, { "from":1000, "to":2000 } ] } } } }
GET test_search_index/_search { "size":0, "aggs":{ "date_range":{ "range":{ #關鍵詞 "field":"birth", "format":"yyyy",#指定返回結果的日期格式 "ranges":[ { "from":"1980",#指定日期,可使用date math "to":"1990" }, { "from":"1990", "to":"2000" } ] } } } }
GET test_search_index/_search { "size":0, "aggs":{ "salary_hist":{ "histogram":{ #關鍵詞 "field":"salary", "interval":5000, #指定間隔大小 "extended_bounds":{ #指定數據範圍 "min":0, "max":40000 } } } } }
Get test_search_index/_search { "size":0, "aggs":{ "by_year":{ "date_historgram":{ #關鍵詞 "field":"birth", "interval":"year", #指定間隔大小 "format":"yyyy" #指定日期格式化 } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":10 }, "aggs" } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ #第一層聚合 "terms":{ "field":"job.keyword", "size":10 }, "aggs":{ "salary":{ #第二層聚合 "stats":{ "field":"salary" } } } } } }
POST order/_search { "size":0, "aggs":{ "sales_per_month":{ "date_histogram":{ "field":"date", "interval":"month" }, "aggs":{ "sales":{ "sum":{ "field":"price" } } } }, "avg_monthly_sales":{ "avg_bucket":{ "bucket_path":"sales_per_month>sales" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":10 }, "aggs":{ "avg_salary":{ "avg":{ "field":"salary" } } } }, "min_salary_by_job":{ "min_bucket":{ #關鍵詞 "buckets_path":"jobs>avg_salary" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":10 }, "aggs":{ "avg_salary":{ "avg":{ "field":"salary" } } } }, "max_salary_by_job":{ "max_bucket":{ "buckets_path":"jobs>avg_salary" } } } }
GET test_search_index/_search { "size":0, "aggs":{ "birth":{ "date_histogram":{ "field":"birth", "interval":"year", "min_doc_count":0 }, "aggs":{ "avg_salary":{ "avg":{ "field":"salary" } }, "derivative_avg_salary":{ "derivative":{ #關鍵詞 "bucket_path":"avg_salary" } } } } } }
GET test_search_index/_search { "size":, "aggs":{ "birth":{ "date_histogram":{ "field":"birth", "interval":"year", "min_doc_count":0 }, "aggs":{ "avg_salary":{ "avg":{ "field":"salary" } }, "mavg_salary":{ "moving_avg":{ #關鍵詞 "buckets_path":"avg_salary" } } } } } }
GET test_search_index/_search { "size":0, "query":{ "match":{#aggs做用域該query的結果集 "username":"alfred" } }, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":10 } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs_salary_small":{ "filter":{ "range":{ "salary":{ "to":10000 } } }, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword" } } } }, "jobs":{ "terms":{ "field":"job.keyword" } } } }
GET test_search_index/_search { "aggs":{ "jobs":{ "terms":{ "field":"job.keyword" } } }, "post_filter":{#過濾條件 "match":{ "job.keyword":"java engineer" } } }
GET test_search_index/_search { "query":{ "match":{ "job.keyword":"java engineer" } }, "aggs":{ "java_avg_salary":{ "avg":{ "field":"salary" } }, "all":{ "global":{}, "aggs":{ "avg_salary":{#過濾條件 "avg":{ "field":"salary" } } } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":10, "order":[ { "count":"asc" }, { "_key":"desc" } ] } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":1, "shard_size":10 } } } }
GET test_search_index/_search { "size":0, "aggs":{ "jobs":{ "terms":{ "field":"job.keyword", "size":2, "show_term_doc_count_error":true } } } }
PUT blog_index_parrent_child { "mappings":{ "doc":{ "properties":{ "join":{ "type":"join",#指明類型 "relations":{#指明父子關係 "blog":"comment" } } } } } }
#建立父文檔 PUT blog_index_parent_child/doc/1 { "title":"blog", "join":"blog" } #建立子文檔 PUT blog_index_parent_child/doc/comment-1?routing=1 #指定routing值,確保父子文檔在一個分片上,通常使用父文檔id { "comment":"comment world", "join":{ "name":"comment", #指明子類型 "parent":1 #指明父文檔id } }
GET blog_index_parent/_search { "query":{ "parent_id":{#關鍵詞 "type":"comment",#指明子文檔類型 "id":"2" #指明父文檔id } } }
GET blog_index_parent/_search { "query":{ "has_child":{#關鍵詞 "type":"comment",#指明子文檔類型 "query":{ "match":{ "comment":"world" } } } } }
GET blog_index_parent/_search { "query":{ "has_parent":{ "has_parent":"blog",#指定父文檔類型 "query":{#指明父文檔查詢條件 "match":{ "title":"blog" } } } } }
對比 | Nested Object | Parent/Child |
---|---|---|
優勢 | 文檔存儲在一塊兒,所以讀取性能高 | 父子文檔能夠獨立更新,互不影響 |
缺點 | 更新父或子文檔時須要更新整個文檔 | 爲了維護join的關係,須要佔用部份內存,讀取性能較差 |
場景 | 子文檔偶爾更新,查詢頻繁 | 子文檔更新頻繁 |
POST blog_index/_update_by_query?conflicts=proceed #若是遇到版本衝突,覆蓋並繼續執行 POST blog_index/_update_by_query { "script":{ #更新文檔的字段值 "source":"ctx._source.likes++", "lang":"painless" }, "query":{ #能夠更新部分文檔 "term":{ "user":"tom" } } }
POST _reindex { "source":{ "index":"blog_index" }, "dest":{ "index":"blog_new_index" } }
POST _reindex { "conflicts":"proceed",#衝突時覆蓋並繼續 "source":{ "index":"blog_index", "query":{ "term":{ "user":"tom" } } }, "dest":{ "index":"blog_new_index" } }
POST blog_index/_update_by_query?wait_for_completion=false #獲取task ID GET _tasks/_qkdskglrfodsm(task ID)
PUT /_cluster/settings { "persistent":{ "discovery.zen.minimum_master_nodes":2 }, "transient":{ "indices.store.throttle.max_bytes_per_sec":"50mb" } }
歡迎各位關注個人公衆號「沒有故事的陳師傅」