《ElasticSearch查詢》目錄導(dǎo)航:

 

ElasticSearch是性能優(yōu)化的分布式全文搜索引擎,存儲(chǔ)數(shù)據(jù)的載體是文檔(Document),它的優(yōu)勢(shì)在于搜索速度快和支持聚合操作,在更新文檔時(shí),基本上能夠達(dá)到實(shí)時(shí)搜索。ElasticSearch引擎總是按照文檔標(biāo)識(shí)來(lái)更新數(shù)據(jù),并發(fā)控制是通過(guò)順序的版本ID(version)實(shí)現(xiàn)的,控制寫(xiě)-寫(xiě)、寫(xiě)-讀沖突,實(shí)現(xiàn)數(shù)據(jù)弱一致性。

在ElasticSearch引擎中,索引定義了文檔的邏輯存儲(chǔ),索引是由段(Segment)組成的,段不是實(shí)時(shí)更新的,這意味著,在建立索引時(shí),一個(gè)段寫(xiě)入磁盤(pán)后,就不再被更新。被刪除文檔的信息存儲(chǔ)在一個(gè)單獨(dú)的文件中,在搜索數(shù)據(jù)時(shí),ElasticSearch首先從段中查詢,再?gòu)牟樵兘Y(jié)果中過(guò)濾被刪除的文檔,這意味著,段中存儲(chǔ)”未被刪除文檔“的密度降低。多個(gè)段可以通過(guò)段合并(Segment Merge)操作把“已刪除”的文檔將從段中物理刪除,將未刪除的文檔合并成一個(gè)新段,新段中沒(méi)有”已刪除文檔“,因此,段合并操作能夠提高索引的查找速度,但段合并是IO密集型的,需要消耗大量的IO操作。

一旦數(shù)據(jù)存儲(chǔ)在倒排索引中,就不能被修改,因此,更新文檔是一項(xiàng)復(fù)雜的任務(wù)。在內(nèi)部,ElasticSearch引擎必須首先獲取文檔(從_source屬性中獲得數(shù)據(jù)),刪除舊的文檔,更新_source屬性,然后重新索引該文檔,使之可被搜索到,就是說(shuō),文檔更新的流程,實(shí)際上是先標(biāo)記文檔被刪除,后插入新的文檔,最后將新文檔編入索引。

數(shù)據(jù)的更新,主要是通過(guò)_update端點(diǎn),編寫(xiě)內(nèi)嵌腳本(inline script)來(lái)實(shí)現(xiàn)。默認(rèn)的腳本語(yǔ)言是Groovy,Groovy是內(nèi)置的腳本語(yǔ)言,不需要安裝,默認(rèn)是禁用的,在未啟用動(dòng)態(tài)腳本的結(jié)點(diǎn)上執(zhí)行腳本更新,ElasticSearch引擎將會(huì)拋出異常消息:

scripts of type [inline], operation [update] and lang [groovy] are disabled

要啟用腳本更新,必須修改每個(gè)節(jié)點(diǎn)(node)的全局配置文件 config/elasticsearch.yml,添加配置選項(xiàng):

script.inline: truescript.indexed: true

一,編入索引(Index Data)

索引API用于將一個(gè)類(lèi)型化的JSON結(jié)構(gòu)添加到一個(gè)索引中,或者更新索引中的一個(gè)文檔,使之能夠被搜索到。

1,使用文檔標(biāo)識(shí)編入索引

在把文檔編入索引時(shí),如果在API中顯式提供文檔的標(biāo)識(shí)(_id),那么ElasticSearch引擎使用Upsert(更新或增加)方式更新索引,這意味著,如果索引中已經(jīng)存在相同ID的文檔,那么ElasticSearch更新該文檔(實(shí)際上是先刪除,后添加);如果索引中不存在相同ID的文檔,那么把文檔添加索引中。

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

PUT host:port/twitter/tweet/1 -d 
{    "user" : "kimchy",    "post_date" : "2009-11-15T14:12:12",    "message" : "trying out Elasticsearch"}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

2,指定操作類(lèi)型

在編入索引時(shí),索引操作支持參數(shù)op_type,用于指定索引數(shù)據(jù)的操作類(lèi)型是create,當(dāng)文檔ID不存在時(shí),將文檔添加到索引中;當(dāng)顯式指定操作類(lèi)型是create時(shí),如果創(chuàng)建的文檔ID已經(jīng)存在于索引中,那么創(chuàng)建操作將失敗。

PUT 'http://localhost:9200/twitter/tweet/1?op_type=create' -d
PUT 'http://localhost:9200/twitter/tweet/1/_create' -d

3,自動(dòng)生成文檔標(biāo)識(shí)

在索引文檔時(shí),如果沒(méi)有指定文檔標(biāo)識(shí),那么ElasticSearch將會(huì)自動(dòng)生成文檔標(biāo)識(shí),并自動(dòng)把操作類(lèi)型(op_type)設(shè)置為create,注意,自動(dòng)生成文檔標(biāo)識(shí)是更新操作,修改索引中的文檔,而不是新建一個(gè)新的文檔,因此使用POST動(dòng)詞,而不是PUT動(dòng)詞。

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

POST 'http://localhost:9200/twitter/tweet/' -d'{
    "user" : "kimchy",    "post_date" : "2009-11-15T14:12:12",    "message" : "trying out Elasticsearch"}'

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

二,刪除文檔

在ElasticSearch引擎中刪除文檔非常簡(jiǎn)單,通過(guò)文檔標(biāo)識(shí)刪除文檔,實(shí)際上,該文檔并沒(méi)有從索引中物理刪除,只是在其他文件中被標(biāo)記刪除,只要ElasticSerach 引擎執(zhí)行段合并操作時(shí),才會(huì)真正從物理上刪除文檔。

DELETE 'http://localhost:9200/twitter/tweet/1'

三,在更新端點(diǎn)(_update)更新文檔

ElasticSearch引擎在更新端點(diǎn)(_update)上更新文檔,更新操作首先從索引中查詢到文檔,執(zhí)行更新邏輯,并將更新之后的文檔重新索引,使之能夠被搜索到。在更新文檔時(shí),ElasticSearch使用版本控制并發(fā)操作可能產(chǎn)生的沖突。更新端點(diǎn)(_update)主要是基于腳本的文檔更新,ElasticSearch引擎從索引中獲取文檔,使用腳本和可選的參數(shù)執(zhí)行更新操作,并將文檔重新編入索引。在更新時(shí),即使只修改文檔的部分字段,ElasticSearch也會(huì)重新索引整個(gè)文檔,并使用文檔版本避免讀-寫(xiě)沖突。使用端點(diǎn)(_update)和內(nèi)嵌腳本對(duì)文檔執(zhí)行更新操作,必須啟用_source 字段。

1,根據(jù)參數(shù)值,更新指定文檔的字段

ctx 是單詞context的縮寫(xiě),表示文檔的上下文,在script節(jié)中,使用ctx引用文檔。

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

POST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : {        "inline": "ctx._source.counter += count",        "params" : { "count" : 4 }
    },    "upsert" : { "counter" : 1  }
}'

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

示例,腳本更新文檔的字段counter,把ID為1的文檔的counter字段增加4。當(dāng)文檔中沒(méi)有該字段時(shí),例如,想要增加文檔中的counter字段值,而該字段不存在,在請(qǐng)求中使用upsert字段,提供counter字段的默認(rèn)值。

upsert參數(shù),當(dāng)指定的文檔不存在時(shí),upsert參數(shù)包含的內(nèi)容將會(huì)被插入到索引中,作為一個(gè)新文檔;如果指定的文檔存在,ElasticSearch引擎將會(huì)執(zhí)行指定的更新邏輯。

例如以下腳本,當(dāng)文檔存在時(shí),把文檔的counter字段設(shè)置為1;當(dāng)文檔不存在時(shí),插入一個(gè)新的文檔,文檔的counter字段的值是2。

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

{  
   "script":{  
      "inline":"ctx._source.counter= 1"
   },   "upsert":{"counter":2}
}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

2,向_source字段,增加一個(gè)字段

POST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.name_of_new_field = \"value_of_new_field\""}'

3,從_source字段中,刪除一個(gè)字段

POST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.remove(\"name_of_field\")"}'

4,根據(jù)提供的文檔片段更新數(shù)據(jù)

使用"doc"字段傳遞文檔片段(Partial Document),doc字段包含完整文檔的一部分字段,ElasticSearch引擎對(duì)已經(jīng)存在的文檔進(jìn)行歸并(Merge)更新,這就意味著,如果文檔中存在doc節(jié)指定的字段,那么替換文檔中的字段值;如果文檔中部存在doc節(jié)指定的字段,那么向文檔中增加新的字段,例如,對(duì)文檔標(biāo)識(shí)為1的文檔,將該文檔中的name字段更新為“new_name”:

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

POST 'localhost:9200/test/type1/1/_update' -d '{
    "doc" : {        "name" : "new_name"
    },   "detect_noop": false}'

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

detect_noop參數(shù),在更新部分文檔時(shí),文檔值被歸并到_source字段,默認(rèn)值是true,這意味著,當(dāng)ElasticSearch引擎會(huì)檢測(cè)_source字段的數(shù)據(jù)發(fā)生變化時(shí),ElasticSearch引擎將重新索引該文檔;如果設(shè)置設(shè)置為False時(shí),ElasticSearch引擎不管_source字段的數(shù)據(jù)是否變化,都會(huì)更新文檔。

5,更新操作的參數(shù)

retry_on_conflict參數(shù):指定更新操作在發(fā)生版本沖突時(shí)重試的次數(shù)。

對(duì)于文檔的更新操作,ElasticSearch引擎需要順序執(zhí)行三個(gè)階段:獲取文檔(Get),更新文檔(Update)和索引文檔(Index)。在更新文檔時(shí),其他進(jìn)程可能已經(jīng)把相同的文檔修改了。在默認(rèn)情況下,更新操作由于檢測(cè)到版本沖突而就立即失敗,拋出異常。參數(shù)retry_on_conflict控制在ElasticSearch引擎真正拋出異常之前,更新操作重新執(zhí)行的次數(shù)。

fields 參數(shù):從已更新的文檔中,返回有關(guān)字段(Relevant Fields)的數(shù)據(jù),如果將fields設(shè)置為_(kāi)source,將返回整個(gè)文檔的所有數(shù)據(jù)。

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

{  
   "doc":{  
      "counter":3
   },   "upsert":{"counter":2},   "fields":["counter"],   "detect_noop":true}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

四,批量操作(_bulk)

批量端點(diǎn)(_bulk)用于在一個(gè)請(qǐng)求(Request)中封裝多個(gè)操作,請(qǐng)求格式是/index_name/type_name/_bulk。在請(qǐng)求主體中,包含多個(gè)操作請(qǐng)求,單個(gè)請(qǐng)求的格式相同,不同之處在于,每個(gè)請(qǐng)求包含兩行JSON對(duì)象:信息行和數(shù)據(jù)行,由于批量端點(diǎn)必須識(shí)別換行,因此,發(fā)送的請(qǐng)求格式 使用--data-binary 代替 -d:

POST /_bulk?pretty  --data-binary  request_body

請(qǐng)求主動(dòng)體,有四種類(lèi)型,分別是index、update、create和delete,實(shí)現(xiàn)數(shù)據(jù)的索引分析,文檔更新,文檔創(chuàng)建和文檔刪除。

1,在索引中增加或替換現(xiàn)有文檔,使用index節(jié)

{"index":{"_index":"index_name","_type":"type_name","_id":####}}
{"doc_field1":"xx","doc_field2":"yy"}

2,從索引中移除文檔,使用delete節(jié)

{"delete":{"_index":"index_name","_type":"type_name","_id":####}}

3,當(dāng)索引中不存在文檔定義時(shí),在索引中增加新文檔,使用create節(jié)

{"create":{"_index":"index_name","_type":"type_name","_id":####}}
{"doc_field1":"xx","doc_field2":"yy"}

4,當(dāng)更新文檔時(shí),使用update節(jié)

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

{ "update" : {"_id" : "1", "_type" : "type1", "_index" : "index1", "_retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"} }
{ "update" : { "_id" : "0", "_type" : "type1", "_index" : "index1", "_retry_on_conflict" : 3} }
{ "script" : { "inline": "ctx._source.counter += param1", "params" : {"param1" : 1}}, "upsert" : {"counter" : 1}}
{ "update" : {"_id" : "2", "_type" : "type1", "_index" : "index1", "_retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"}, "upsert" : true }
{ "update" : {"_id" : "3", "_type" : "type1", "_index" : "index1", "fields" : ["_source"]} }
{ "doc" : {"field" : "value"} }
{ "update" : {"_id" : "4", "_type" : "type1", "_index" : "index1"} }
{ "doc" : {"field" : "value"}, "fields": ["_source"]}

電腦培訓(xùn),計(jì)算機(jī)培訓(xùn),平面設(shè)計(jì)培訓(xùn),網(wǎng)頁(yè)設(shè)計(jì)培訓(xùn),美工培訓(xùn),Web培訓(xùn),Web前端開(kāi)發(fā)培訓(xùn)

 

參考文檔:

Elasticsearch Reference [2.4] ? Document APIs

Elasticsearch Reference [2.4] ? Document APIs ? Bulk API

Elasticsearch Reference [2.4] ? Document APIs ? Update API

Elasticsearch Reference [2.4] ? Modules ? Scripting

--業(yè)精于勤而荒于嬉,行成于思而毀于隨--
--歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處--

分類(lèi): ElasticSearch

http://www.cnblogs.com/ljhdo/p/4885796.html