目錄
使用查詢再打分來減少評分操作的性能影響(7.x似乎缺少相關屬性??)
使用function_score來定製得分(7.x引入了script_score)
elasticSearch語法摘錄
2020-06-21: notepad++中刪除空格換行回車等方式,ctrl+f ==> 勾選循環查找和正則表達式 ==>替換欄輸入\s 即可.
準備相關:
刪除docker鏡像 docker rmi id或標籤
使用tag爲鏡像添加標籤: docker tag 舊repostery:tag 新repostery:tag
當repostery不同,tag相同,imageID也相同的時候,使用docker rmi respostery:tag 刪除不想要的image.
查看正在運行的容器: docker ps
啓動已經停止的容器實例: docker start id
啓動未啓動過的容器實例: docker run. 有三個參數 1) -it,以交互方式啓動;2) -p 映射內外部端口; 3) -d 以附加進程啓動
進入docker容器:docker exec -it id前3位(可以模糊查詢) /bin/bash ; 退出可以直接輸入exit
停止一個正在運行的容器: docker stop 容器ID或容器名 有一個參數 -t,給容器時間(秒)去保存自己的狀態:dcoker stop -t=20
直接立即關閉容器:docker kill 容器名ID
重啓一個容器: docker restart ID或名稱 對於正在運行的容器進行重啓就可以加-t給一個保存狀態的時間.
查看容器: docker inspect 容器名
刪除容器: docker rm -v:直接刪除容器,並解除與之關聯的卷. -l db是移除容器甲對容器乙的連接db;-f db01 db02是刪除容器db01和db02
清理臨時的沒有被使用的鏡像文件:docker image prune(慎用!)
查看層級歷史:docker history ID
docker啓動es
9200端口用於外部通信,9300用於集羣內部通信.
docker run -p 9200:9200 elasticsearch ,然後瀏覽器中調es所在ip:9200查看是否啓動成功
索引是由一個或多個被稱爲分片的數據塊組成.易於擴展
索引有分片,分片有副本,分片和副本可存在於不同的節點.當有3個節點5個分片和5個副本時:深色爲分片,淺色爲副本
一個es服務是一個節點,或者一個es進程也是一個節點.多個節點可以加入同一個集羣.默認情況下可以連接集羣中任意一個節點並訪問完整的數據集(完整的數據集不限於單個節點).
當索引一篇文檔時,系統首先根據文檔ID的散列值選擇一個主分片將該文檔發送過去,這個主分片可能位於別的節點(機器,線程).然後主分片開始同步該文檔至所有副分片.搜索該文檔時,es需要在該索引的完整分片集合中進行查找,這些分片可能是主分片也可能是副分片.
一份分片是Lucene的索引:一個包含倒排索引的文件目錄.一個es索引由多個Lucene索引組成.副分片可以在運行的時候進行添加和移除,主分片不可以.過多的分片會影響性能.
分佈式索引和搜索.索引時一旦確定文檔所在分片,接受請求的節點將文檔發送到分片所在節點.然後同步至所有副本.搜索時接受請求的節點將請求轉發到一組包含所有數據的分片(可以是不同的節點上).es使用round-robin的輪訓機制選擇可用的分片(主分片或副分片).並將搜索請求轉發過去.然後es從這些分片收集結果,將其聚集到單一的回覆返回給客戶端.
索引新數據
cURL的使用: -X此處不帶空格[GET默認可以不帶-X PUT PIST]; 單引號'ip:9200/索引/ID?pretty'
添加一個文檔的命令:
curl -XPOST -H "Content-Type:application/json" '192.168.1.103:9200/get-together/1?pretty' -d '{"name":"Elasticsearch","organizer":"chow"}'
//返回
{
"_index" : "get-together",
"_type" : "1",
"_id" : "ol8p0XIBV6yKmAPNJs-g",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
[root@localhost ~]# curl -XPUT '192.168.1.103:9200/new-index'
{"acknowledged":true,"shards_acknowledged":true,"index":"new-index"}
查看mapping的命令:
[root@localhost ~]# curl '192.168.1.103:9200/get-together/_mapping?pretty'
全文查找的 例子:這裏加不了&fields=name,location\
[root@localhost ~]# curl "192.168.1.103:9200/get-together/_search?\
q=elasticsearch\
&size=1\
&pretty"
//es7.x已經移除type
可以寫成&q=name,location:elasticsearch
[root@localhost ~]# curl "192.168.1.103:9200/get-together/_search?\
q=name:elasticsearch\
&size=1\
&pretty"
索引處可以加多個索引,用逗號隔開.也可以省略索引直接在所有索引間搜索.將不同範圍的數據構建到不同的索引裏,而不是一個大索引?
請求參數可以加"timeout=3s",設定請求在超過3秒後超時.此時只能獲得這期間查到的內容.
返回結果中的"_shards"一欄會返回成功命中的分片以及失敗的分片.即便有分片宕機,依然可以返回剩餘分片的查詢結果.
es默認限制結果數量爲10.使用size參數修改返回的數量.
使用json格式制定搜索條件:
[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"query_string":{"query":"Denver"}}}'
單query裏指定多條件字段的AND查詢可以這樣寫:注意query裏面的AND一定要大寫
[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"query_string":{"query":"name:Denver AND location_group:Denver"}}}'
選擇合適的查詢類型:使用term
curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"term":{"name":"elasticsearch"}}}'
使用過濾器:
如果對打分不感興趣,使用過濾器更快更適合緩存.使用filter要配合bool查詢.max_score項爲0.0.不會根據得分排序.
curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"bool":{"filter":{"term":{"name":"elasticsearch"}}}}}'
應用聚合:
對沒有優化或加索引的字段聚合會報錯.
[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"aggregations":{"organizers":{"terms":{"field":"organizer"}}}}'
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [organizer] in order to load field data by uninverting the inverted index. Note that this can use significant memory."
優化方式就是set fielddata=true .注意這裏是_mapping相關操作
[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_mapping?pretty' -d '{"properties":{"organizer":{"type":"text","fielddata":true}}}'
{
"acknowledged" : true
}
在此聚合,就可以了.
"aggregations" : {
"organizers" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "lee",
"doc_count" : 2
},
{
"key" : "andy",
"doc_count" : 1
},
{
"key" : "daniel",
"doc_count" : 1
},
{
"key" : "mik",
"doc_count" : 1
},
{
"key" : "tyler",
"doc_count" : 1
}
]
}
}
通過ID獲取文檔:
/_doc不能少
curl '192.168.1.103:9200/get-together/_doc/1?pretty'
配置es集羣
1.elasticsearch.yml中指定集羣的名稱 cluster.name 改名稱後原有數據將不可見,不是丟失.
2.logging.yml中編輯日誌選項 cluster-name.log;超過半秒的慢搜索日誌:cluster-name_index_search_slowlog.log;超過半秒的慢索引(索引相關操作)日誌:cluster-name_index_indexing_slowlog.log.
3.在環境變量或elasticsearch.in.sh中調整內存設置.這是配置java虛擬機 在文件開始部分加ES_HEAP_SIZE=500m.默認是256MB 實際生產中如果機器只運行es,可以將heap_size設置爲最多一半的機器內存.
索引更新和刪除數據
有3種類型的字段:基本字段,數組和多元字段,預定義字段.可以用預定義字段_ttl設置過期文檔自動刪除.
查看所有索引
[root@localhost ~]# curl "192.168.1.103:9200/_cat/indices?v"
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open indexforputandmapping gi0ZFKysRD6g1cO7ieTefA 1 1 1 0 4kb 4kb
yellow open get-together bM_WypSDQBma_mL4cHMdKA 2 1 20 0 45.2kb 45.2kb
yellow open myindex Fqk1gJbrTL6vyZ9eKXD0rg 1 1 0 0 208b 208b
yellow open november_2014_invoices QEbTWlFMQJWPPWwXfss45A 1 1 0 0 208b 208b
yellow open december_2014_invoices eMBBAX8WRKCAEAeUmZEixg 1 1 0 0 208b 208b
yellow open new-index iN-g0oqpQt6Qza6CmKqVtQ 1 1 0 0 208b 208b
green open .kibana_1 oRggM7WgRA-sN218C_WEkg 1 0 1 0 3.8kb 3.8kb
使用mapping來定義各種文檔
獲取目前的映射
curl '192.168.1.103:9200/get-together/_mapping?pretty'
索引一篇新的文檔
[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/indexforputandmapping/1?pretty' -d '{"name":"Late Night with Elasticsearch","date":"2013-10-25T19:00"}'
{
"_index" : "indexforputandmapping",
"_type" : "1",
"_id" : "yV-d1nIBV6yKmAPNM89t",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
查看上面的新mapping
[root@localhost ~]# curl '192.168.1.103:9200/indexforputandmapping/_mapping?pretty'
{
"indexforputandmapping" : {
"mappings" : {
"properties" : {
"date" : {
"type" : "date"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
定義新的mapping
定義新的字段host,類型爲text.es7.x移除了string,8之後會徹底移除.
[root@localhost ~]# curl -XPUT -H 'Content-Type:application/json' '192.168.1.103:9200/indexforputandmapping/_mapping?pretty' -d '{"properties":{"host":{"type":"text"}}}'
{
"acknowledged" : true
}
可以每次只添加新字段,mapping會自動合併.再次查看該索引:
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/indexforputandmapping/_mapping?pretty'
{
"indexforputandmapping" : {
"mappings" : {
"properties" : {
"date" : {
"type" : "date"
},
"host" : {
"type" : "text"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
用於定義文檔字段的核心類型
請參考這篇文章: https://blog.csdn.net/Mikowoo007/article/details/106585422
7.x 有字符串類:text,keyword;
數值型:long,integer,short,byte,double,float,half_float,scaled_float;布爾型:boolean;二進制型:binary默認不存儲不搜索;
範圍類型:integer_range,float_range,date_range等,譬如 age 的類型是 integer_range
, 那麼值可以是 {“gte”:20, “lte”: 40}:搜索 “term” {“age”:21} 可以搜索該值;
日期型:date 通過格式來判斷是否屬於date類型;
複雜數據類型:array 直接用[]定義,數組中的類型必須一致,可以是object對象數組;
對象類型:Object 查詢時使用點操作符指定字段名;
專用數據類型: IP,經緯度geo_point等
常用字段類型的查詢
先插一條數據
[root@localhost ~]# curl "192.168.1.103:9200/new-index/_mapping?pretty"
{
"new-index" : {
"mappings" : { }
}
}
[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/1?pretty' -d '{"name":"Late Night with Elasticsearch","date":"2013-10-25T19:00"}'
{
"_index" : "new-index",
"_type" : "1",
"_id" : "yl8A13IBV6yKmAPNIc-T",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
查詢.默認分詞器將所有字符轉化爲小寫,query_string的效果:會對搜索詞進行分詞,然後在text類型(也會分詞)中去匹配,詞詞之間可以不連續詞序也可以調換.match_phrase則要求(所分的詞)必須連續且順序.請參考:https://www.cnblogs.com/chenmz1995/p/10199147.html
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_search?pretty' -d '{"query":{"query_string":{"query":"late"}}}'
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "new-index",
"_type" : "1",
"_id" : "yl8A13IBV6yKmAPNIc-T",
"_score" : 0.2876821,
"_source" : {
"name" : "Late Night with Elasticsearch",
"date" : "2013-10-25T19:00"
}
}
]
}
}
對於不需要搜索的字段可以設置index爲no,以節省空間,加快索引及搜索過程.
數組和多字段
數組 :如果要索引擁有多個值的字段,將這些值放在方括號中.數組在mapping中的type是裏面數據的基本類型.
多字段:使用多字段可以對同一個字段設置不同的type及index屬性.這裏演示給tag字段加上一個不索引的配置的字段.注意配置"index":false
[root@localhost ~]# curl -XPUT -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_mapping?pretty' -d '{"properties":{"date":{"type":"date"},"name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"tags":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256},"verbatim":{"type":"text","index":false}}}}}' {
"acknowledged" : true
}
再查看該索引的mapping就會發現tag字段的mapping變了
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_mapping?pretty' {
"new-index" : {
"mappings" : {
"properties" : {
"date" : {
"type" : "date"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"tags" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
},
"verbatim" : {
"type" : "text",
"index" : false
}
}
}
}
}
}
}
使用預定義字段
/_cat/indices:查看所有索引
C:\Users\admin>curl localhost:9200/_cat/indices?pretty
_source:返回所有數據,如果只要返回某些字段,可以加上&_source=字段名
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_search?pretty&_source=name'
{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "new-index",
"_type" : "1",
"_id" : "yl8A13IBV6yKmAPNIc-T",
"_score" : 1.0,
"_source" : {
"name" : "Late Night with Elasticsearch"
}
},
{
"_index" : "new-index",
"_type" : "1",
"_id" : "zV9E13IBV6yKmAPNVs-r",
"_score" : 1.0,
"_source" : { }
}
]
}
}
還可以使用filter_path將took,timeout,_shards等過濾掉(不選即不顯示):這裏只顯示了?pretty&filter_path=hits.hits._source&_source=name
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_search?pretty&filter_path=hits.hits._source&_source=name'
{
"hits" : {
"hits" : [
{
"_source" : {
"name" : "Late Night with Elasticsearch"
}
},
{
"_source" : { }
}
]
}
}
更新現有的文檔
文檔的更新包括檢索文檔,處理文檔,並重新索引文檔,直至先前的文檔被覆蓋.
使用 /_update
更新前:
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/2?pretty'
{
"_index" : "get-together",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"relationship_type" : "group",
"name" : "Elasticsearch Denver",
"organizer" : "Lee",
"description" : "Get together to learn more about using Elasticsearch, the applications and neat things you can do with ES!",
"created_on" : "2013-03-15",
"tags" : [
"denver",
"elasticsearch",
"big data",
"lucene",
"solr"
],
"members" : [
"Lee",
"Mike"
],
"location_group" : "Denver, Colorado, USA"
}
}
更新時:
[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/2/_update?pretty' -d '{"doc":{"organizer":"Roy"}}'
{
"_index" : "get-together",
"_type" : "_doc",
"_id" : "2",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 16,
"_primary_term" : 1
}
更新後:organizer改變,_version改變
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/2?pretty' {
"_index" : "get-together",
"_type" : "_doc",
"_id" : "2",
"_version" : 2,
"_seq_no" : 16,
"_primary_term" : 1,
"found" : true,
"_source" : {
"relationship_type" : "group",
"name" : "Elasticsearch Denver",
"organizer" : "Roy",
"description" : "Get together to learn more about using Elasticsearch, the applications and neat things you can do with ES!",
"created_on" : "2013-03-15",
"tags" : [
"denver",
"elasticsearch",
"big data",
"lucene",
"solr"
],
"members" : [
"Lee",
"Mike"
],
"location_group" : "Denver, Colorado, USA"
}
}
如果之前文檔不存在,那麼這裏會操作失敗並提示文檔缺失.同時也應該使用版本去避免併發修改.
使用與doc同級的upsert參數來創建不存在的修改
id爲20的文檔先前不存在,先upsert
[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/20/_update?pretty' -d '{"doc":{"organizer":"chow"},"upsert":{"name":"Elasticsearch Denver","organizer":"chow"}}'
{
"_index" : "get-together",
"_type" : "_doc",
"_id" : "20",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
再查看,已有
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/20?pretty' {
"_index" : "get-together",
"_type" : "_doc",
"_id" : "20",
"_version" : 1,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "Elasticsearch Denver",
"organizer" : "chow"
}
}
通過腳本來更新文檔
可以實現:1)改值 2)刪字段 等
默認的腳本語言是Grovvy;
腳本涉及到修改並重新索引文檔,所以使用ctx._source來引用_source, 使用ctx_source.字段名 來引用某個指定的字段;
如果涉及到變量,建議在params下作爲參數單獨定義.參數與腳本分離,這樣腳本只需要編譯一次.
修改前:
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/online-shop/shirts/1?pretty'
{
"_index" : "online-shop",
"_type" : "shirts",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"price" : 15
}
}
修改中:這裏的+=後面一定要用params引出參數名
[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/online-shop/shirts/1/_update?pretty' -d '{"script":{"inline":"ctx._source.price += params.price_diff","params":{"price_diff":10}}}'
{
"_index" : "online-shop",
"_type" : "shirts",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
修改後:
[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/online-shop/shirts/1?pretty' {
"_index" : "online-shop",
"_type" : "shirts",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"price" : 25
}
}
遇到一些語法報錯問題,參考了這篇文章: https://blog.csdn.net/sanbingyutuoniao123/article/details/79687195
向數組中添加還需要在腳本中使用add()方法.
通過版本來實現併發控制
模擬併發修改.此處改成在Kibana中調用es
POST /online-shop/shirts/1/_update
{
"script":"Thread.sleep(5000);ctx._source.price = 2"
}
POST /online-shop/shirts/1/_update
{
"script":"ctx._source.caption = \"Knowing Elasticsearch\""
}
樂觀鎖,假設很少出現衝突.真的出現衝突的時候就報錯.悲觀鎖則通過鎖住可能引起衝突的操作預防衝突.
此處可以設置/_update?retry_on_conflict=3讓es自動在衝突時重試.
可以設置使用外部版本:?version_type=external
刪除數據
刪除單個或部分文檔,先標記後異步刪除;刪除整個索引幾乎瞬間就能完成;還可以關閉索引
刪除文檔
根據id刪除單個文檔:也可以有版本控制
DELETE /online-shop/shirts/1
刪除查詢匹配的文檔:
Kibana的搜索
直接刪除索引:
DELETE /online-shop
關閉索引: 索引名/_close 打開索引:索引名/_open
搜索數據
關鍵詞:query,size,from,_source,sort
GET /get-together/_search
{
"from":0,
"size": 10,
"sort":[{"date":"desc"}],
"_source":{
"includes": ["date","title"] //可以不加includes或excludes,直接跟在_source後面
}
}
介紹查詢和過濾器DSL
GET /get-together/_search
{
"query":{
"match": {
"title": "hadoop"
}
}
}
term屬於過濾器.
常用的基礎查詢和過濾器:
1) query_string的用法
GET /get-together/_search
{
"query":{
"query_string": {
"default_field": "description",
"query": "nosql"
}
}
}
query中可以帶上Lucene的表達式,可以使用 AND OR TO 以及使用減號"-"進行結果剔除.
GET /get-together/_search
{
"query":{
"query_string": {
"default_field": "description",
"query": "(tags:search OR tags:lucene) AND created_on:[1999-01-01 TO 2001-01-01] AND -description:mongodb"
}
}
}
2) term查詢和term過濾器
GET /get-together/_search
{
"query":{
"term":{
"tags": "elasticsearch"
}
}
}
term過濾:filter要配合bool使用.max_score不再評分
GET /get-together/_search
{
"query": {
"bool": {
"filter": {
"term": {
"tags": "elasticsearch"
}
}
}
}
}
3)terms查詢
GET /get-together/_search
{
"query": {
"terms": {
"tags": [
"elasticsearch",
"jvm"
]
}
}
}
4) match查詢和term過濾器
match查詢是一個散列映射,包含了希望搜索的字段和字符串.match查詢 可以有多重方式,最常見的是boolean和詞組phrase.
1.布爾查詢方式: match會分詞,這裏查詢的是Elasticsearch 和 Denver
GET /get-together/_search
{
"query": {
"match": {
"name": {
"query": "Elasticsearch Denver",
"operator": "and" //默認是or
}
}
}
}
2.詞組查詢方式 允許詞與詞之間可以有別的詞
GET /get-together/_search
{
"query": {
"match": {
"name": {
//7.x沒有type
"query": "enterprise london"
//7.x沒有slop
}
}
}
}
還可以用詞的開頭去匹配
GET /get-together/_search
{
"query": {
"match": {
"name": {
"query": "Elasticsearch Den",
"max_expansions": 1
}
}
}
}
3.使用multi_match來匹配多個字段,注意fields數組裏的字段類型和query的類型
GET /online-shop/shirts/_search
{
"query":{
"multi_match": {
"query": "haha",
"fields": ["caption","name"]
}
}
}
組合查詢或複合查詢
bool查詢
GET /online-shop/shirts/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"name": "hadoop"
}
}
],
"should": [
{
"term": {
"name": "hadoop"
}
},
{
"term": {
"name": "1"
}
}
],
"must_not": [
{
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
bool過濾器
query不能直接跟filter,需要用bool包一層.must和should包在同一層真的沒問題嗎?
GET /online-shop/shirts/_search
{
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"term": {
"name": "hadoop"
}
}
],
"should": [
{
"term": {
"name": "hadoop"
}
},
{
"term": {
"name": "1"
}
}
],
"must_not": [
{
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
}
}
range查詢和過濾器
GET /online-shop/shirts/_search
{
"query":{
"range": {
"FIELD": {
"gte": 10,
"lte": 20
}
}
}
}
過濾器形式:
GET /online-shop/shirts/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"FIELD": {
"gte": 10,
"lte": 20
}
}
}
]
}
}
}
prefix查詢和過濾器
GET /online-shop/shirts/_search
{
"query": {
"prefix": {
"caption": {
"value": "e"
}
}
}
}
可用於根據輸入實時查詢,如果要帶有一定的模糊性,可以使用match_phrase_prefix
wildcard通配符查詢
*匹配任意數量字符,?匹配一個字符.?無法匹配空格.通配符出現的越早,查詢性能越低.類似的有regexp查詢.
GET /online-shop/shirts/_search
{
"query": {
"wildcard": {
"caption": {
"value": "l*n"
}
}
}
}
exists過濾器
只查詢特定字段有值的文檔.
GET /get-together/_search
{
"query": {
"bool":{
"filter": [
{
"exists": {
"field": "tags"
}
}
]
}
}
}
高版本es filter的寫法改爲在bool中指定filter,並移除了missing的api(7.x已移除),可以在 bool must not 中指定exists代表不存在
分析數據
字符過濾->分詞->分詞過濾->索引數據
match,match_phrase會對查詞進行分詞分析.term和terms不會.
如果要對字段進行分析,在mapping的該字段下設置analyzer參數;如果不想分析,可以設置該字段的index屬性爲not_analyzed.
還可以通過fields屬性設置不同的分詞分析方式.
分析器包括:字符過濾器,一個單個分詞器,0或多個分詞過濾器.
關於keyword analyzer,最好是在映射中將涉及的字段設爲not_analyzed.
N元語法(ngram)和edge-ngram和滑動窗口
ngram是將一個詞進行一個字符間距的分割或多個指定字符間距的分割.可以設置min_gram和max_gram.會以min到max之間的間距分別分割字符串.可用於具有一定相似度的模糊查詢.
edge-ngram的分詞方式是始終從一側開始包含詞頭,分詞數量相對較少.可以通過設置side屬性來指定從詞尾開始分詞.
滑動窗口類似上面的分詞,但它是分詞級別的N元語法,而不像上面的那樣是字符串級別的.滑動窗口適用於查詢英語中連續的短語.
使用相關性進行搜索
詞頻和逆文檔頻率.Lucene評分公式TF-IDF基於此.
更換字段的打分方案是在mapping中字段屬性下設置similarity屬性.也可以在setting中設置更高級的配置.
使用boosting來影響文檔的得分
GET /online-shop/shirts/_search
{
"query": {
"boosting": {
"positive": {
"match": {
"caption": "Elasticsearch"
}
},
"negative": {
"multi_match": {
"fields": [
"acption",
"name"
],
"query": "hadoop"
}
},
"negative_boost": 0.2
}
}
}
boost大致是加權的作用.將所有字段的boost設置相同的值等於都沒設置.
基本所有的查詢都能設置boost,除此以外還可以通過function_score更精細的來控制boosting.
可以使用explain來解釋分值的形成.舉例如下:
GET /online-shop/shirts/_search
{
"query": {
"match": {
"caption": "hadoop"
}
},
"explain": true
}
解釋一篇文檔不匹配的原因
需要先知道文檔的id,然後使用/_explain進行分析.
GET /online-shop/shirts/1/_explain
{
"query": {
"match": {
"caption": "java"
}
}
}
//返回結果
{
"_index" : "online-shop",
"_type" : "shirts",
"_id" : "1",
"matched" : false,
"explanation" : {
"value" : 0.0,
"description" : "no matching term",
"details" : [ ]
}
使用查詢再打分來減少評分操作的性能影響(7.x似乎缺少相關屬性??)
在下列情況下打分可能會變成資源密集型的操作:
1.使用腳本來計算每篇
2.進行phrase詞組查詢.
使用function_score來定製得分(7.x引入了script_score)
GET /online-shop/shirts/_search
{
"query": {
"function_score": {
"query": {
"match": {
"caption": "hadoop"
}
},
"functions": [
{
"weight": 2, //相當於原boost * 2
"filter": { //在上述查詢結果中過濾出caption字段含"elasticSearch"的
"term": {
"caption": "elasticsearch"
}
}
}
]
}
}
}
function_score查詢有一組不同的函數,每個函數可以使用另一個過濾器函數.
合併得分
上面的functions數組中可以放多個weight,每個weight的分值可以不一樣.那麼可以通過score_mode參數(multiply,sum,avg,fitst,max,min.如果沒有說明默認是multiply)來合併不同函數的得分.
還有一種是boost_mode.它控制了原始查詢的得分和函數得分是如何合併的.
1)field_value_factor
2)script_score
3)random_score
如果不想第一頁永遠展示那幾個文檔,可以設不同的seed
GET /get-together/_search
{
"query": {
"function_score": {
"query": {
"match": {
"description": "elasticsearch"
}
},
"functions": [
{
"random_score": {
"seed": 31415926535
}
}
]
}
},
"size": 2
}
4)衰減函數
如果想要最近的文檔優先展示,老的文檔靠後.或者在地理位置上靠近某個點的結果增加得分,遠離的結果減少得分.可以使用這個函數.根據熱度,時間,距離進行打分.