Elasticsearch 常用查詢語句理解

pretty
在任意的查詢字符串中增加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"
  } ]
}


【原創】原創文章,更多關注敬請關注微信公衆號。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章