Elasticsearch
通用能力
- 查看文檔數(shù)量
GET http://192.168.1.243:9200/_count
{
"query": {
"match_all": {}
}
}
<<
{
"count": 272053,
"_shards": {
"total": 2,
"successful": 2,
"skipped": 0,
"failed": 0
}
}
- 集群健康
GET /_cluster/health
<<
{
"cluster_name": "elasticsearch",
"status": "green",
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}
status 字段指示著當(dāng)前集群在總體上是否工作正常。它的三種顏色含義如下:
green
所有的主分片和副本分片都正常運(yùn)行。
yellow
所有的主分片都正常運(yùn)行,但不是所有的副本分片都正常運(yùn)行。
red
有主分片沒(méi)能正常運(yùn)行。
創(chuàng)建數(shù)據(jù)和檢索
- 創(chuàng)建記錄
PUT http://192.168.1.243:9200/megacorp/employee/1
-----------------------------索引名稱(chēng)---類(lèi)型名稱(chēng)---ID--------------------------
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
<<
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
如果想讓 ES 自動(dòng)創(chuàng)建 ID 請(qǐng)把 PUT 方法換成 POST, 自動(dòng)生成的 ID 是 URL-safe、 基于 Base64 編碼且長(zhǎng)度為20個(gè)字符的 GUID 字符串。 這些 GUID 字符串由可修改的 FlakeID 模式生成,這種模式允許多個(gè)節(jié)點(diǎn)并行生成唯一 ID ,且互相之間的沖突概率幾乎為零。
- HEAD 方法檢查文檔是否存在
- 更新文檔
PUT /website/blog/123
{
"title": "My first blog entry",
"text": "I am starting to get the hang of this...",
"date": "2014/01/02"
}
- 刪除文檔
DELETE /website/blog/123
- ID 查詢
GET http://192.168.1.243:9200/megacorp/employee/1
<<
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}
}
返回文檔的一部分
GET http://192.168.1.243:9200/megacorp/employee/1?_source=first_name,age
只要 _source 不要元數(shù)據(jù)
GET /website/blog/123/_source
- 檢索
http://192.168.1.243:9200/precisiongenes_search_engine/_search
<<
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": 1.0,
"hits": [
{
"_index": "precisiongenes_search_engine",
"_type": "_doc",
"_id": "bd3ad591114e491938b8a7ff8f8932e3",
"_score": 1.0,
"_source": {
"Chr": "11",
"Start": "119216858",
"End": "119216858",
"Ref": "G",
"Alt": "A",
"HGMD_acc": "CM1926607",
"HGMD_Disease": "Nanophthalmos",
"HGMD_tag": "DM",
"HGMD_rankscore": "0.99",
"HGMD_Base": "CGA-TGA",
"HGMD_HGVS": "MFRP:NM_031433.4:c.169C>T:NP_113621.1:p.R57*",
"HGMD_Mutation_URL": "CGA-TGA|Arg57Term|c.169C>T|- (http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=31589614&dopt=Abstract)",
"HGMD_PmidAll": "NULL\n"
}
}
]
}
}
- 搜索條件
http://192.168.1.243:9200/precisiongenes_search_engine/_search?q=HGMD_Mutation_URL:CGA-TGA
<<
{
"took": 25,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": 6.579259,
"hits": [
{
"_index": "precisiongenes_search_engine",
"_type": "_doc",
"_id": "bd3ad591114e491938b8a7ff8f8932e3",
"_score": 6.579259,
"_source": {
"Chr": "11",
"Start": "119216858",
"End": "119216858",
"Ref": "G",
"Alt": "A",
"HGMD_acc": "CM1926607",
"HGMD_Disease": "Nanophthalmos",
"HGMD_tag": "DM",
"HGMD_rankscore": "0.99",
"HGMD_Base": "CGA-TGA",
"HGMD_HGVS": "MFRP:NM_031433.4:c.169C>T:NP_113621.1:p.R57*",
"HGMD_Mutation_URL": "CGA-TGA|Arg57Term|c.169C>T|- (http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=31589614&dopt=Abstract)",
"HGMD_PmidAll": "NULL\n"
}
}
]
}
}
- 查詢表達(dá)式
GET http://192.168.1.243:9200/precisiongenes_search_engine/_search
BODY
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
<<
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": 6.579259,
"hits": [
{
"_index": "precisiongenes_search_engine",
"_type": "_doc",
"_id": "bd3ad591114e491938b8a7ff8f8932e3",
"_score": 6.579259,
"_source": {
"Chr": "11",
"Start": "119216858",
"End": "119216858",
"Ref": "G",
"Alt": "A",
"HGMD_acc": "CM1926607",
"HGMD_Disease": "Nanophthalmos",
"HGMD_tag": "DM",
"HGMD_rankscore": "0.99",
"HGMD_Base": "CGA-TGA",
"HGMD_HGVS": "MFRP:NM_031433.4:c.169C>T:NP_113621.1:p.R57*",
"HGMD_Mutation_URL": "CGA-TGA|Arg57Term|c.169C>T|- (http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=31589614&dopt=Abstract)",
"HGMD_PmidAll": "NULL\n"
}
}
]
}
}
- 更復(fù)雜的搜索
GET /megacorp/employee/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": {
"range" : {
"age" : { "gt" : 24 }
}
}
}
}
}
<<
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_score": 0.2876821,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}
}
]
}
}
- 短語(yǔ)搜索
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
<<
{
...
"hits": {
"total": 1,
"max_score": 0.23013961,
"hits": [
{
...
"_score": 0.23013961,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
}
]
}
}
- 高亮搜索
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
<<
{
...
"hits": {
"total": 1,
"max_score": 0.23013961,
"hits": [
{
...
"_score": 0.23013961,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
},
"highlight": {
"about": [
"I love to go <em>rock</em> <em>climbing</em>"
]
}
}
]
}
}
- 聚合分析
GET /megacorp/employee/_search
{
// ------- query 可以不帶---------
"query": {
"match": {
"last_name": "smith"
}
},
// ------------------------------
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}
<<
{
...
"hits": { ... },
"aggregations": {
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "forestry",
"doc_count": 1
},
{
"key": "sports",
"doc_count": 1
}
]
}
}
}
- 聚合分析-分級(jí)匯總
查詢特定興趣愛(ài)好員工的平均年齡
GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}
<<
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2,
"avg_age": {
"value": 28.5
}
},
{
"key": "forestry",
"doc_count": 1,
"avg_age": {
"value": 35
}
},
{
"key": "sports",
"doc_count": 1,
"avg_age": {
"value": 25
}
}
]
}
最牛的功能——搜索
- 空搜索
GET /_search GET /_search?timeout=10ms
- 多索引,多類(lèi)型
/_search
在所有的索引中搜索所有的類(lèi)型
/gb/_search
在 gb 索引中搜索所有的類(lèi)型
/gb,us/_search
在 gb 和 us 索引中搜索所有的文檔
/g*,u*/_search
在任何以 g 或者 u 開(kāi)頭的索引中搜索所有的類(lèi)型
/gb/user/_search
在 gb 索引中搜索 user 類(lèi)型
/gb,us/user,tweet/_search
在 gb 和 us 索引中搜索 user 和 tweet 類(lèi)型
/_all/user,tweet/_search
在所有的索引中搜索 user 和 tweet 類(lèi)型
- 分頁(yè)
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
輕量搜索
查詢?cè)?tweet 類(lèi)型中 tweet 字段包含 elasticsearch 單詞的所有文檔
GET /_all/tweet/_search?q=tweet:elasticsearch
查詢?cè)?name 字段中包含 john 并且在 tweet 字段中包含 mary 的文檔
+name:john +tweet:mary
但是查詢字符串參數(shù)所需要的 百分比編碼:
GET /_search?q=%2Bname%3Ajohn+%2Btweet%3Amary
+ 前綴表示必須與查詢條件匹配。類(lèi)似地, - 前綴表示一定不與查詢條件匹配。沒(méi)有 + 或者 - 的所有其他條件都是可選的——匹配的越多,文檔就越相關(guān)。
- _all 字段
GET /_search?q=mary
當(dāng)索引一個(gè)文檔的時(shí)候,Elasticsearch 取出所有字段的值拼接成一個(gè)大的字符串,作為 _all 字段進(jìn)行索引
+name:(mary john) +date:>2014-09-10 +(aggregations geo)
name 字段中包含 mary 或者 john
date 值大于 2014-09-10
_all 字段包含 aggregations 或者 geo
?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)
映射和分析
基于對(duì)字段類(lèi)型的猜測(cè), Elasticsearch 動(dòng)態(tài)為我們產(chǎn)生一個(gè)映射,由于 _all 是默認(rèn)字段,所以沒(méi)有提及它。但是我們知道 _all 字段是 string 類(lèi)型的。
Elasticsearch 支持如下簡(jiǎn)單域類(lèi)型:
- 字符串:
string - 整數(shù) :
byte,short,integer,long - 浮點(diǎn)數(shù):
float,double - 布爾型:
boolean - 日期:
date
這意味著如果你通過(guò)引號(hào)( "123" )索引一個(gè)數(shù)字,它會(huì)被映射為 string 類(lèi)型,而不是 long 。但是,如果這個(gè)域已經(jīng)映射為 long ,那么 Elasticsearch 會(huì)嘗試將這個(gè)字符串轉(zhuǎn)化為 long ,如果無(wú)法轉(zhuǎn)化,則拋出一個(gè)異常。
查看類(lèi)型 http://36.152.126.130:9200/megacorp/_mapping/
自定義域映射-跳過(guò)
index
index 屬性控制怎樣索引字符串。它可以是下面三個(gè)值:
-
analyzed首先分析字符串,然后索引它。換句話說(shuō),以全文索引這個(gè)域。
-
not_analyzed索引這個(gè)域,所以它能夠被搜索,但索引的是精確值。不會(huì)對(duì)它進(jìn)行分析。
-
no不索引這個(gè)域。這個(gè)域不會(huì)被搜索到。
查詢與過(guò)濾
過(guò)濾情況 :查詢被設(shè)置成一個(gè)“不評(píng)分”或者“過(guò)濾”查詢;只是簡(jiǎn)單的檢查包含或者排除,這就使得計(jì)算起來(lái)非???,結(jié)果會(huì)被緩存到內(nèi)存中以便快速讀取。
查詢情況 :查詢就變成了一個(gè)“評(píng)分”的查詢;不僅僅要找出匹配的文檔,還要計(jì)算每個(gè)匹配文檔的相關(guān)性,計(jì)算相關(guān)性使得它們比不評(píng)分查詢費(fèi)力的多。同時(shí),查詢結(jié)果并不緩存。
語(yǔ)句
-
match_all查詢簡(jiǎn)單的匹配所有文檔。在沒(méi)有指定查詢方式時(shí),它是默認(rèn)的查詢
{ "match_all": {}}
-
match如果你在一個(gè)全文字段上使用match查詢,在執(zhí)行查詢前,它將用正確的分析器去分析查詢字符串;如果在一個(gè)精確值的字段上使用它,例如數(shù)字、日期、布爾或者一個(gè)not_analyzed字符串字段,那么它將會(huì)精確匹配給定的值。
{ "match": { "tweet": "About Search" }}
{ "match": { "age": 26 }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}
query對(duì)于精確值的查詢,你可能需要使用 filter 語(yǔ)句來(lái)取代 query,因?yàn)?filter 將會(huì)被緩存。multi_match查詢可以在多個(gè)字段上執(zhí)行相同的match查詢。
{
"multi_match": {
"query": "full text search",
"fields": [ "title", "body" ]
}
}
-
range查詢找出那些落在指定區(qū)間內(nèi)的數(shù)字或者時(shí)間
{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
-
term查詢被用于精確值匹配,這些精確值可能是數(shù)字、時(shí)間、布爾或者那些not_analyzed的字符串
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
{ "term": { "public": true }}
{ "term": { "tag": "full_text" }}
- 字符串被索引的時(shí)候是被 analyzed 的,有一些關(guān)鍵自負(fù)的丟失,不支持精確索引,而且一旦被 analysis 將不能再轉(zhuǎn)變?yōu)?not_analyzed
查看 analyzed 的結(jié)果:
GET /my_store/_analyze
{
"field": "productID",
"text": "XHDK-A-1293-#fJ3"
}
<<<
{
"tokens" : [ {
"token" : "xhdk",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 1
}, {
"token" : "a",
"start_offset" : 5,
"end_offset" : 6,
"type" : "<ALPHANUM>",
"position" : 2
}, {
"token" : "1293",
"start_offset" : 7,
"end_offset" : 11,
"type" : "<NUM>",
"position" : 3
}, {
"token" : "fj3",
"start_offset" : 13,
"end_offset" : 16,
"type" : "<ALPHANUM>",
"position" : 4
} ]
}
Elasticsearch 用 4 個(gè)不同的 token 而不是單個(gè) token 來(lái)表示這個(gè) UPC 。
所有字母都是小寫(xiě)的。
丟失了連字符和哈希符#
所以當(dāng)我們用 term 查詢查找精確值 XHDK-A-1293-#fJ3 的時(shí)候,找不到任何文檔,因?yàn)樗⒉辉谖覀兊牡古潘饕校缜懊娉尸F(xiàn)出的分析結(jié)果,索引里有四個(gè) token 。
此時(shí)只能刪除索引重新創(chuàng)建映射然后重建數(shù)據(jù)來(lái)支持精確索引
DELETE /my_store
PUT /my_store
{
"mappings" : {
"products" : {
"properties" : {
"productID" : {
"type" : "string",
"index" : "not_analyzed"
}
}
}
}
}
-
terms查詢和term查詢一樣,但它允許你指定多值進(jìn)行匹配。**一定要了解term和terms是 包含(contains) 操作,而非 等值(equals) (判斷)。 **精確相等的話,解決方法是創(chuàng)建另一個(gè)輔助字段。
{ "terms": { "tag": [ "search", "full_text", "nosql" ] }}
{
"terms" : {
"price" : [20, 30]
}
}
-
exists查詢和missing查詢被用于查找那些指定字段中有值 (exists) 或無(wú)值 (missing) 的文檔。這與SQL中的IS_NULL(missing) 和NOT IS_NULL(exists) 在本質(zhì)上具有共性,這些查詢經(jīng)常用于某個(gè)字段有值的情況和某個(gè)字段缺值的情況。
{
"exists": {
"field": "title"
}
}
-
組合多查詢
-
must文檔 必須 匹配這些條件才能被包含進(jìn)來(lái)。
-
must_not文檔 必須不 匹配這些條件才能被包含進(jìn)來(lái)。
-
should如果滿足這些語(yǔ)句中的任意語(yǔ)句,將增加
_score,否則,無(wú)任何影響。它們主要用于修正每個(gè)文檔的相關(guān)性得分。 -
filter必須 匹配,但它以不評(píng)分、過(guò)濾模式來(lái)進(jìn)行。這些語(yǔ)句對(duì)評(píng)分沒(méi)有貢獻(xiàn),只是根據(jù)過(guò)濾標(biāo)準(zhǔn)來(lái)排除或包含文檔。
-
復(fù)合(Compound) 語(yǔ)句 主要用于 合并其它查詢語(yǔ)句。 比如,一個(gè) bool 語(yǔ)句 允許在你需要的時(shí)候組合其它語(yǔ)句,無(wú)論是 must 匹配、 must_not 匹配還是 should 匹配,同時(shí)它可以包含不評(píng)分的過(guò)濾器(filters)
{
"bool": {
"must": { "match": { "tweet": "elasticsearch" }},
"must_not": { "match": { "name": "mary" }},
"should": { "match": { "tweet": "full text" }},
"filter": { "range": { "age" : { "gt" : 30 }} }
}
}
找出信件正文包含 business opportunity 的星標(biāo)郵件,或者在收件箱正文包含 business opportunity 的非垃圾郵件
{
"bool": {
"must": { "match": { "email": "business opportunity" }},
"should": [
{ "match": { "starred": true }},
{ "bool": {
"must": { "match": { "folder": "inbox" }},
"must_not": { "match": { "spam": true }}
}}
],
"minimum_should_match": 1
}
}
如果我們不想因?yàn)槲臋n的時(shí)間而影響得分,可以用 filter 語(yǔ)句來(lái)重寫(xiě)前面的例子
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"range": { "date": { "gte": "2014-01-01" }}
}
}
}
range 查詢已經(jīng)從 should 語(yǔ)句中移到 filter 語(yǔ)句, 通過(guò)將 range 查詢移到 filter 語(yǔ)句中,我們將它轉(zhuǎn)成不評(píng)分的查詢,將不再影響文檔的相關(guān)性排名。由于它現(xiàn)在是一個(gè)不評(píng)分的查詢,可以使用各種對(duì) filter 查詢有效的優(yōu)化手段來(lái)提升性能。
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }}
],
"filter": {
"bool": {
"must": [
{ "range": { "date": { "gte": "2014-01-01" }}},
{ "range": { "price": { "lte": 29.99 }}}
],
"must_not": [
{ "term": { "category": "ebooks" }}
]
}
}
}
}
-
constant_scoreterm 查詢被放置在 constant_score 中,轉(zhuǎn)成不評(píng)分的 filter。這種方式可以用來(lái)取代只有 filter 語(yǔ)句的 bool 查詢。{ "constant_score": { "filter": { "term": { "category": "ebooks" } } } } 驗(yàn)證查詢
validate-query API 可以用來(lái)驗(yàn)證查詢是否合法。
GET /gb/tweet/_validate/query?explain
{
"query": {
"tweet" : {
"match" : "really powerful"
}
}
}
<<
{
"valid" : false,
"_shards" : { ... },
"explanations" : [ {
"index" : "gb",
"valid" : false,
"error" : "org.elasticsearch.index.query.QueryParsingException:
[gb] No query registered for [tweet]"
} ]
}
排序
ES 默認(rèn)通過(guò) _score 降序排列,可以調(diào)整排序字段,如果調(diào)整到其他字段就不再計(jì)算 score 值。
- 排序
GET /_search
{
"query" : {
"bool" : {
"filter" : { "term" : { "user_id" : 1 }}
}
},
"sort": { "date": { "order": "desc" }}
}
- 多級(jí)排序,結(jié)果首先按第一個(gè)條件排序,僅當(dāng)結(jié)果集的第一個(gè)
sort值完全相同時(shí)才會(huì)按照第二個(gè)條件進(jìn)行排序,以此類(lèi)推。
GET /_search
{
"query" : {
"bool" : {
"must": { "match": { "tweet": "manage text search" }},
"filter" : { "term" : { "user_id" : 2 }}
}
},
"sort": [
{ "date": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
}
Query-string 搜索 也支持自定義排序,可以在查詢字符串中使用 sort 參數(shù):
GET /_search?sort=date:desc&sort=_score&q=search
- 多值字段排序, 對(duì)于數(shù)字或日期,你可以將多值字段減為單值,這可以通過(guò)使用
min、max、avg或是sum排序模式 。
"sort": {
"dates": {
"order": "asc",
"mode": "min"
}
}
相關(guān)性
Elasticsearch 的相似度算法被定義為檢索詞頻率/反向文檔頻率, TF/IDF ,包括以下內(nèi)容:
-
檢索詞頻率
檢索詞在該字段出現(xiàn)的頻率?出現(xiàn)頻率越高,相關(guān)性也越高。 字段中出現(xiàn)過(guò) 5 次要比只出現(xiàn)過(guò) 1 次的相關(guān)性高。
-
反向文檔頻率
每個(gè)檢索詞在索引中出現(xiàn)的頻率?頻率越高,相關(guān)性越低。檢索詞出現(xiàn)在多數(shù)文檔中會(huì)比出現(xiàn)在少數(shù)文檔中的權(quán)重更低。
-
字段長(zhǎng)度準(zhǔn)則
字段的長(zhǎng)度是多少?長(zhǎng)度越長(zhǎng),相關(guān)性越低。 檢索詞出現(xiàn)在一個(gè)短的 title 要比同樣的詞出現(xiàn)在一個(gè)長(zhǎng)的 content 字段權(quán)重更大。
單個(gè)查詢可以聯(lián)合使用 TF/IDF 和其他方式,比如短語(yǔ)查詢中檢索詞的距離或模糊查詢里的檢索詞相似度。