solr更新document parts

 

Updating Parts of Documents

 

一旦索引了solr索引中所需的內容,您將要開始考慮處理這些文檔更改的策略。SOLR支持三種更新僅部分更改的文檔的方法。

 

第一個是原子更新。這種方法只允許更改文檔的一個或多個字段,而不必重新索引整個文檔。

第二種方法稱爲就地更新。這種方法類似於原子更新(從某種意義上說是原子更新的一個子集),但只能用於更新單值、非索引和非存儲的基於docvalue的數字字段。

第三種方法稱爲樂觀併發或樂觀鎖。它是許多NoSQL數據庫的一個特性,允許根據文檔的版本有條件地更新文檔。這種方法包括如何處理版本匹配或錯誤匹配的語義和規則。

原子更新(和就地更新)和樂觀併發可以用作管理文檔更改的獨立策略,也可以組合使用:可以使用樂觀併發有條件地應用原子更新。

 

原子更新

 

solr支持幾個自動更新文檔值的修飾符。這隻允許更新特定的字段,這有助於在索引添加速度對應用程序至關重要的環境中加快索引過程。

要使用原子更新,請向需要更新的字段添加一個修飾符。如果字段具有數字類型,則可以更新、添加或增量增加內容。

set

使用指定的值設置或替換字段值,或者如果將“null”或空列表指定爲新值,則刪除這些值。

可以指定爲單個值,也可以指定爲多值字段的列表。

add

將指定的值添加到多值字段。可以指定爲單個值,也可以指定爲列表。

add-distinct

將指定的值添加到多值字段中(僅當尚未存在時)。可以指定爲單個值,也可以指定爲列表。

remove

從多值字段中刪除(所有出現的)指定值。可以指定爲單個值,也可以指定爲列表。

removeregex

從多值字段中刪除指定regex的所有出現項。可以指定爲單個值,也可以指定爲列表。

inc

以特定的量遞增一個數值。必須指定爲單個數值。

 

Field Storage

原子更新文檔的核心功能要求架構中的所有字段必須配置爲存儲(stored=“true”)或docvalues(docvalues=“true”),但目標爲<copyfield/>的字段除外,這些字段必須配置爲stored=“false”。原子更新應用於由現有存儲字段值表示的文檔。“CopyField目標”字段中的所有數據必須僅源自CopyField源。

如果將<copy field/>目的地配置爲已存儲,那麼solr將嘗試索引該字段的當前值以及來自任何源字段的其他副本。如果這樣的字段包含來自索引程序的一些信息和來自CopyField的一些信息,那麼最初來自索引程序的信息將在進行原子更新時丟失。

還必須設置其他類型的派生字段,以便不存儲它們。一些空間字段類型(如bboxfield和latlontype)使用派生字段。currencyFieldType還使用派生字段。這些類型創建通常由動態字段定義指定的其他字段。不能存儲該動態字段定義,否則索引將失敗。

例子:

如果以下document存在於我們的集合中:

 

{"id":"mydoc",

 "price":10,

 "popularity":42,

 "categories":["kids"],

 "sub_categories":["under_5","under_10"],

 "promo_ids":["a123x"],

 "tags":["free_to_try","buy_now","clearance","on_sale"]

}

 

我們應用以下更新命令:

{"id":"mydoc",

 "price":{"set":99},

 "popularity":{"inc":20},

 "categories":{"add":["toys","games"]},

 "sub_categories":{"add-distinct":"under_10"},

 "promo_ids":{"remove":"a123x"},

 "tags":{"remove":["free_to_try","on_sale"]}

}

結果文檔是:

{"id":"mydoc",

 "price":99,

 "popularity":62,

 "categories":["kids","toys","games"],

 "sub_categories":["under_5","under_10"],

 "tags":["buy_now","clearance"]

}

 

就地更新

就地更新與原子更新非常相似;在某種意義上,這是原子更新的一個子集。在常規的原子更新中,整個文檔在應用更新期間會在內部重新索引。但是,在這種方法中,只有要更新的字段會受到影響,其餘的文檔不會在內部重新索引。因此,就地更新的效率不受被更新的文檔的大小(即,字段的數量、字段的大小等)的影響。除了這些內部差異之外,原子更新和就地更新之間沒有功能差異。

只有當要更新的字段滿足以下三個條件時,才使用此方法執行原子更新操作:

1、are non-indexed (indexed="false"), non-stored (stored="false"), single valued (multiValued="false") numeric docValues (docValues="true") fields;

2、the _version_ field is also a non-indexed, non-stored single valued docValues field; and,

3、copy targets of updated fields, if any, are also non-indexed, non-stored single valued numeric docValues fields.

 

要使用就地更新,請向需要更新的字段添加修改器。內容可以更新或增量增加。

 

set

用指定的值設置或替換字段值。可以指定爲單個值。

inc

按特定數量遞增數值。必須指定爲單個數值。

 

就地更新示例

如果價格和流行度字段在模式中定義爲:

<field name="price" type="float" indexed="false" stored="false" docValues="true"/>

<field name="popularity" type="float" indexed="false" stored="false" docValues="true"/>

如果以下document存在於我們的集合中:

 

{

 "id":"mydoc",

 "price":10,

 "popularity":42,

 "categories":["kids"],

 "promo_ids":["a123x"],

 "tags":["free_to_try","buy_now","clearance","on_sale"]

}

我們應用以下更新命令:

{

 "id":"mydoc",

 "price":{"set":99},

 "popularity":{"inc":20}

}

結果文檔是:

{

 "id":"mydoc",

 "price":99,

 "popularity":62,

 "categories":["kids"],

 "promo_ids":["a123x"],

 "tags":["free_to_try","buy_now","clearance","on_sale"]

}

 

樂觀的併發控制

樂觀併發是solr的一個特性,它可以被更新/替換文檔的客戶端應用程序使用,以確保它們正在替換/更新的文檔沒有被另一個客戶端應用程序同時修改。此功能的工作原理是要求索引中的所有文檔都有一個“版本”_version_ 字段,並將其與作爲更新命令一部分指定的“版本”_version_ 進行比較。默認情況下,solr的模式包括一個版本字段_version_ ,該字段將自動添加到每個新文檔中。

通常,使用樂觀併發涉及以下工作流程:

  1. 客戶讀取文檔。在solr中可以使用/get處理程序檢索文檔以確保具有最新版本_version_ 。
  2. 客戶端在本地更改文檔。
  3. 將更改後的文檔重新提交給solr。例如,可能使用/update處理程序
  4. 如果存在版本衝突(HTTP錯誤代碼409),客戶端將重新啓動進程。

當客戶將更改後的文檔重新提交給solr時,可以在更新中包含_version_ ,以調用樂觀併發控制。特定的語義用於定義何時應該更新文檔或何時報告衝突。

  1. 如果“版本_version_”字段中的內容大於“1”(例如“12345”),則文檔中的“版本_version_”必須與索引中的“版本_version_”匹配。
  2. 如果“版本”字段中的內容等於“1”,則文檔必須簡單存在。在這種情況下,不會發生版本匹配,但如果文檔不存在,則更新將被拒絕。
  3. 如果“版本”字段中的內容小於“0”(即“-1”),則文檔必須不存在。在這種情況下,不會發生版本匹配,但如果文檔存在,則更新將被拒絕。
  4. 如果“版本”字段中的內容等於“0”,那麼版本是否匹配或文檔是否存在並不重要。如果它存在,它將被覆蓋;如果它不存在,它將被添加。

如果正在更新的文檔不包含版本字段,並且未使用原子更新,則該文檔將按常規solr規則處理,這通常是爲了放棄以前的版本。

使用樂觀併發時,客戶機可以包含可選的versions=true請求參數,以指示要添加的文檔的新版本應包括在響應中。這允許客戶立即知道添加的每個文檔的版本,而無需發出冗餘/獲取請求。

以下是一些在查詢中使用versions=true的示例:

$ curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/techproducts/update?versions=true' --data-binary '[ { "id" : "aaa" },  { "id" : "bbb" } ]'

 

 

{"responseHeader":{"status":0,"QTime":6},

 "adds":["aaa",1498562471222312960,

         "bbb",1498562471225458688]}

在這個例子中,我們添加了2個文檔“aaa”和“bbb”。因爲我們在請求中添加了versions=true,所以響應會顯示每個文檔的文檔版本。

 

$ curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/techproducts/update?_version_=999999&versions=true' --data-binary '[{ "id" : "aaa",   "foo_s" : "update attempt with wrong existing version" }]'

 

{"responseHeader":{"status":409,"QTime":3},

 "error":{"msg":"version conflict for aaa expected=999999 actual=1498562471222312960",

          "code":409}}

在本例中,我們試圖更新文檔“aaa”,但在請求中指定了錯誤的版本:version=999999與添加文檔時獲得的文檔版本不匹配。我們得到了一個錯誤的響應。

$ curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/techproducts/update?_version_=1498562471222312960&versions=true&commit=true' --data-binary '[{ "id" : "aaa",   "foo_s" : "update attempt with correct existing version" }]'

 

{"responseHeader":{"status":0,"QTime":5},

 "adds":["aaa",1498562624496861184]}

現在,我們已經發送了一個更新,其中包含與索引中的值匹配的版本值,並且成功了。因爲我們將versions=true包含在更新請求中,所以響應中包含了一個不同的值。

 

$ curl 'http://localhost:8983/solr/techproducts/query?q=*:*&fl=id,_version_'

 

{

  "responseHeader":{

    "status":0,

    "QTime":5,

    "params":{

      "fl":"id,_version_",

      "q":"*:*"}},

  "response":{"numFound":2,"start":0,"docs":[

      {

        "id":"bbb",

        "_version_":1498562471225458688},

      {

        "id":"aaa",

        "_version_":1498562624496861184}]

  }}

最後,我們可以發出一個查詢,請求在響應中包含“版本”字段,我們可以看到示例索引中的兩個文檔。

有關更多信息,請參見Yonik Seeley在Apache Lucene Eurocon 2012的Solr 4中關於NoSQL功能的演示。

 

以文檔爲中心的版本控制約束

樂觀併發性非常強大,而且工作效率非常高,因爲它使用內部分配的、全局唯一的值作爲_version_字段。但是,在某些情況下,用戶可能希望配置自己的文檔特定版本字段,其中版本值由外部系統根據每個文檔分配,並讓SOLR拒絕嘗試用“舊”版本替換文檔的更新。在這種情況下,DocBasedVersionConstraintsProcessorFactory 可能很有用。

DocBasedVersionConstraintsProcessorFactory 的基本用法是在solrconfig.xml中將其配置爲updateRequestProcessorChain的一部分,並在架構中指定在驗證更新時應檢查的自定義版本字段的名稱:

<processor class="solr.DocBasedVersionConstraintsProcessorFactory">

  <str name="versionField">my_version_l</str>

</processor>

 

注意,versionField是一個用逗號分隔的字段列表,用於檢查版本號。配置後,此更新處理器將拒絕(HTTP錯誤代碼409)任何更新現有文檔的嘗試,其中“新”文檔中“my_version_l”字段的值不大於現有文檔中該字段的值。

 

versionField_version_

solr用於其正常樂觀併發性的“_version_”字段在如何將更新分發到solrcloud中的副本中也具有重要的語義,並且必須由solr在內部分配。用戶不能重新使用該字段並將其指定爲在docbasedversionConstraintsProcessorFactory配置中使用的版本字段versionField。

DocbasedversionConstraintsProcessorFactory支持以下附加配置參數,這些參數都是可選的:

 

ignoreOldUpdates

默認爲false的布爾選項。如果設置爲真,更新將被靜默忽略(並向客戶端返回狀態200),而不是拒絕版本字段過低的更新。

deleteVersionParam

A String parameter that can be specified to indicate that this processor should also inspect Delete By Id commands.

The value of this option should be the name of a request parameter that the processor will consider mandatory for all attempts to Delete By Id, and must be be used by clients to specify a value for the versionField which is greater then the existing value of the document to be deleted.

When using this request parameter, any Delete By Id command with a high enough document version number to succeed will be internally converted into an Add Document command that replaces the existing document with a new one which is empty except for the Unique Key and versionField to keeping a record of the deleted version so future Add Document commands will fail if their "new" version is not high enough.

If versionField is specified as a list, then this parameter too must be specified as a comma delimited list of the same size so that the parameters correspond with the fields.

supportMissingVersionOnOldDocs

此布爾參數默認爲false,但如果設置爲true,則允許覆蓋在此功能啓用之前寫入的任何文檔,並且這些文檔缺少版本字段。

 

https://lucene.apache.org/solr/7_7_0//solr-core/org/apache/solr/update/processor/DocBasedVersionConstraintsProcessorFactory.html

 

https://gitbox.apache.org/repos/asf?p=lucene-solr.git;a=blob;f=solr/core/src/test-files/solr/collection1/conf/solrconfig-externalversionconstraint.xml;hb=HEAD

 

原地址:http://lucene.apache.org/solr/guide/7_7/updating-parts-of-documents.html

 

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