在任意的查詢字符串中增加pretty參數,會讓Elasticsearch美化輸出(pretty-print)JSON響應以便更加容易閱讀。
GET /website/blog/123?pretty
針對性過濾輸出
GET /website/blog/123?_source=title,text
如果你想做的只是檢查文檔是否存在,使用HEAD方法來代替GET。HEAD請求不會返回響應體,只有HTTP頭:
curl -i -XHEAD http://localhost:9200/website/blog/123
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0
請求成功的創建了一個新文檔,Elasticsearch將返回正常的元數據且響應狀態碼是201 Created,如果文檔已存在,Elasticsearch將返回409 Conflict響應狀態碼。
解決衝突:
1.在讀一行數據前鎖定這行,然後確保只有加鎖的那個線程可以修改這行數據。
2.在讀寫過程中數據發生了變化,更新操作將失敗。這時候由程序決定在失敗後如何解決衝突。實際情況中,可以重新嘗試更新,刷新數據(重新讀取)或者直接反饋給用戶。
如果需要從Elasticsearch中檢索多個文檔,相對於一個一個的檢索,更快的方式是在一個請求中使用multi-get或者mget API。mget是針對讀,針對所有主從分片。
POST /_mget
{
"docs" : [
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website",
"_type" : "pageviews",
"_id" : 1,
"_source": "views"
}
]
}
bulk API允許我們使用單一請求來實現多個文檔的create、index、update或delete。針對主分片操作。
POST /_bulk
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "Cannot create - it already exists" }
{ "index": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "But we can update it" }
整個批量請求需要被加載到接受我們請求節點的內存裏,所以請求越大,給其它請求可用的內存就越小。有一個最佳的bulk請求大小。超過這個大小,性能不再提升而且可能降低。
路由文檔到分片
當你索引一個文檔,它被存儲在單獨一個主分片上。Elasticsearch是如何知道文檔屬於哪個分片的呢?當你創建一個新文檔,它是如何知道是應該存儲在分片1還是分片2上的呢?
進程不能是隨機的,因爲我們將來要檢索文檔。事實上,它根據一個簡單的算法決定:
shard = hash(routing) % number_of_primary_shards
routing值是一個任意字符串,它默認是_id但也可以自定義。這個routing字符串通過哈希函數生成一個數字,然後除以主切片的數量得到一個餘數(remainder),餘數的範圍永遠是0到
number_of_primary_shards - 1,這個數字就是特定文檔所在的分片。
這也解釋了爲什麼主分片的數量只能在創建索引時定義且不能修改:如果主分片的數量在未來改變了,所有先前的路由值就失效了,文檔也就永遠找不到了。
replication複製
複製默認的值是sync。這將導致主分片得到複製分片的成功響應後才返回。設置replication爲async,請求在主分片上被執行後就會返回給客戶端。它依舊會轉發請求給複製節點,但將不知道複製
節點成功與否。
consistency
默認主分片在嘗試寫入時需要規定數量(quorum)或過半的分片(可以是主節點或複製節點)可用。
int( (primary + number_of_replicas) / 2 ) + 1 number_of_replicas是複製分片的數量。
數據檢索
1.客戶端給Node 1發送get請求。
2.節點使用文檔的_id確定文檔屬於分片0。分片0對應的複製分片在三個節點上都有。負載均衡轉發請求到Node 2。
3.Node 2返回文檔(document)給Node 1然後返回給客戶端。
搜索:
hits:響應中最重要的部分是hits,它包含了total字段來表示匹配到的文檔總數,hits數組還包含了匹配到的前10條數據。每個節點都有一個_score字段,這是相關性得分(relevance score),
它衡量了文檔與查詢的匹配程度。按照_score降序排列的
took告訴我們整個搜索請求花費的毫秒數。
time_out值告訴我們查詢超時與否。
{
"hits" : {
"total" : 14,
"hits" : [
{
"_index": "us",
"_type": "tweet",
"_id": "7",
"_score": 1,
"_source": {
"date": "2014-09-17",
"name": "John Smith",
"tweet": "The Query DSL is really powerful and flexible",
"user_id": 2
}
},
... 9 RESULTS REMOVED ...
],
"max_score" : 1
},
"took" : 4,
"_shards" : {
"failed" : 0,
"successful" : 10,
"total" : 10
},
"timed_out" : false
}
多索引和多類別:
GET /_all/tweet/_search?q=tweet:elasticsearch _all:所有文檔
/_search
在所有索引的所有類型中搜索
/gb/_search
在索引gb的所有類型中搜索
/gb,us/_search
在索引gb和us的所有類型中搜索
/g*,u*/_search
在以g或u開頭的索引的所有類型中搜索
Elasticsearch分頁展示,接受from和size參數:
size: 結果數,默認10
from: 跳過開始的結果數,默認0
如果你想每頁顯示5個結果,頁碼從1到3,那請求如下:
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
映射(mapping)機制用於進行字段類型確認,將每個字段匹配爲一種確定的數據類型(string, number, booleans, date等)。
分析(analysis)機制用於進行全文文本(Full Text)的分詞,以建立供搜索用的反向索引。
例:Elasticsearch在對gb索引中的tweet類型進行mapping,Elasticsearch爲對字段類型進行猜測,動態生成了字段和類型的映射關係
date類型的字段和string類型的字段的索引方式是不同的,查詢匹配日期結果也是不同的。
{
"gb": {
"mappings": {
"tweet": {
"properties": {
"date": {
"type": "date",
"format": "dateOptionalTime"
},
"name": {
"type": "string"
},
"tweet": {
"type": "string"
},
"user_id": {
"type": "long"
}
}
}
}
}
}
Elasticsearch中的數據可以大致分爲兩種類型:
確切值確定的,正如它的名字一樣。比如一個date或用戶ID,確切值"Foo"和"foo"就並不相同。確切值2014和2014-09-15也不相同。
全文文本,文本化的數據,全文文本常常被稱爲非結構化數據,匹配程度查詢,例如一封郵件
分析器:
當你查詢全文(full text)字段,查詢將使用相同的分析器來分析查詢字符串,以產生正確的詞列表。全文檢索需要分詞。
當你查詢一個確切值(exact value)字段,查詢將不分析查詢字符串,但是你可以自己指定。確切值查詢不需要分詞。
Elasticsearch支持以下簡單字段類型:
類型 表示的數據類型
String string
Whole number byte, short, integer, long
Floating point float, double
Boolean boolean
Date date
查看映射:
GET /gb/_mapping/tweet
index值 解釋
analyzed 首先分析這個字符串,然後索引。換言之,以全文形式索引此字段。
not_analyzed 索引這個字段,使之可以被搜索,但是索引內容和指定值一樣。不分析此字段。
no 不索引這個字段。這個字段不能爲搜索到。
string類型字段默認值是analyzed。如果我們想映射字段爲確切值,我們需要設置它爲not_analyzed:
{
"tag": {
"type": "string",
"index": "not_analyzed"
}
}
葉子子句(leaf clauses)(比如match子句)用以在將查詢字符串與一個字段(或多字段)進行比較
複合子句(compound)用以合併其他的子句。例如,bool子句允許你合併其他的合法子句,must,must_not或者should,如果可能的話:
{
"bool": {
"must": { "match": { "tweet": "elasticsearch" }},
"must_not": { "match": { "name": "mary" }},
"should": { "match": { "tweet": "full text" }}
}
}
must :: 多個查詢條件的完全匹配,相當於 and。
must_not :: 多個查詢條件的相反匹配,相當於 not。
should :: 至少有一個查詢條件匹配, 相當於 or。
結構化查詢(Query DSL)查詢語句會詢問每個文檔的字段值與特定值的匹配程度如何
結構化過濾(Filter DSL)一條過濾語句會詢問每個文檔的字段值是否包含着特定值
最常用到的查詢過濾語句:
term主要用於精確匹配哪些值,比如數字,日期,布爾值或 not_analyzed的字符串(未經分析的文本數據類型)
terms 跟 term 有點類似,但 terms 允許指定多個匹配條件。
range過濾允許我們按照指定範圍查找一批數據
範圍操作符包含:
gt :: 大於
gte:: 大於等於
lt :: 小於
lte:: 小於等於
exists 和 missing 過濾可以用於查找文檔中是否包含指定字段或沒有某個字段
validate API 可以驗證一條查詢語句是否合法。
GET /gb/tweet/_validate/query
{
"query": {
"tweet" : {
"match" : "really powerful"
}
}
}
以上請求的返回值告訴我們這條語句是非法的:
{
"valid" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
}
}
理解查詢語句:使用 explain 參數可以返回一個帶有查詢語句的可閱讀描述
GET /_validate/query?explain
{
"query": {
"match" : {
"tweet" : "really powerful"
}
}
}
explanation 會爲每一個索引返回一段描述,因爲每個索引會有不同的映射關係和分析器:
{
"valid" : true,
"_shards" : { ... },
"explanations" : [ {
"index" : "us",
"valid" : true,
"explanation" : "tweet:really tweet:powerful"
}, {
"index" : "gb",
"valid" : true,
"explanation" : "tweet:really tweet:power"
} ]
}
【原創】原創文章,更多關注敬請關注微信公衆號。