solr數據操作


本文介紹solr的基本數據操作,基於solr 8.2。solr支持多種數據格式,包括XML,JSON,CSV等,並提供多種腳本和工具來操作數據。本文講解curl請求和JSON數據格式的處理方式。

本文使用單solr服務來演示數據操作,創建名為 my_core 的solr core, 文檔schema如下:

<schema name="my" version="1.0">
  <uniqueKey>id</uniqueKey>
  <fieldType name="string" class="solr.StrField" sortMissingLast="true"/>
  <field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
  <field name="author" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
  <field name="title" type="string" indexed="true" required="true" stored="true" multiValued="false"/>
  <field name="tags" type="string" multiValued="true" indexed="true" stored="true"/>
</schema>

插入文檔

插入單個文檔

最基本的數據操作就是插入單個文檔:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update/json/docs?commit=true' --data-binary '
{
  "id": "0132350882",
  "author": "Robert C. Martin",
  "title": "Clean Code: A Handbook of Agile Software Craftsmanship",
  "tags": [
    "Computer Programming Languages",
    "Software Testing",
    "Software Design & Engineering"
  ]
}'

參數說明:

  1. -X POST : 設置HTTP請求類型為POST,后續所有操作都為POST請求
  2. -H 'Content-Type: application/json' : 設置請求格式為JSON
  3. http://localhost:8983/solr/my_core/update/json/docs?commit=true: 請求地址URL和查詢參數。其中 http://localhost:8983 為solr服務的地址和端口, my_core 為文檔插入的core名稱,可以根據自己的實際情況調整。 comment=true 參數表示此操作要進行同步提交。如果不設置此參數, solr則會根據 solrconfig.xml 文件 UpdateHandler 配置薦中的 autoCommit 配置延遲提交修改。
  4. --data-binary :此參數指定操作所需的JSON數據,這里是新插入的文檔。

以上curl命令的幾個參數在后續的操作中都會用到,用法也基本相同。

錯誤信息

當操作有誤時,solr的響應體會包含錯誤信息。比如,當執行以下操作時:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update/json/docs' --data-binary '
{
  "id": "0132350882",
  "title": "Clean Code: A Handbook of Agile Software Craftsmanship"
}'

因為請求的JSON數據缺少了必需的字段 author ,solr會返回以下的錯誤信息:

{
  "responseHeader":{
    "status":400,
    "QTime":6},
  "error":{
    "metadata":[
      "error-class","org.apache.solr.common.SolrException",
      "root-error-class","org.apache.solr.common.SolrException"],
    "msg":"[doc=0132350882] missing required field: author",
    "code":400}}

此時,可以根據信息中的 msg 字段以及solr的日志來排查問題所在。后續其他操作的錯誤信息也會遵循類似的行為。

插入多個文檔

如果希望在同一個請求入插入多個文檔,只需要將文檔數據以JSON數組的組織即可:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update/json/docs?commit=true' --data-binary '
[
  {
    "id": "0132350882",
    "author": "Robert C. Martin",
    "title": "Clean Code: A Handbook of Agile Software Craftsmanship",
    "tags": [
      "Computer Programming Languages",
      "Software Testing",
      "Software Design & Engineering"
    ]
  },
  {
    "id": "0201633612",
    "author": "Erich Gamma",
    "title": "Design Patterns: Elements of Reusable Object-Oriented Software",
    "tags": [
        "Object-Oriented Design",
        "Software Reuse",
        "Object-Oriented Software Design"
    ]
  }
]'

修改文檔

覆寫現有文檔

修改文檔的一種方式是使用solr的JSON命令接口來覆寫現有的文檔。比如在按照前文中的例子插入文檔 0132350882 后,執行:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update?commit=true' --data-binary '
{
  "add": {
    "doc": {
      "id": "0132350882",
      "author": "Robert C. Martin",
      "title": "Clean Code"
    }
  }
}'

此操作和之前的插入操作有以下不同:

  1. 請求路徑變為 /solr/my_core/update ,而不是 /solr/my_core/update/json/docs
  2. 請求體中的JSON需要 add 節點來表示操作類型。 add 節點下的 doc 子節點是需要修改的文檔。add 下還可以添加其他節點,來指定操作的其他參數,比如 overwrite 。這里不再展開。

solr會根據schema中配置的主鍵來查詢已有的文檔記錄,這里是 id,並用 doc 節點的內容覆寫已有文檔,所以 doc 節點需要給出完成的文檔內容,沒有出現在 doc 節點中的屬性會從文檔中刪除。在這此例中,執行完操作后,文檔 0132350882title 屬性會被修改,而 tags 屬性則會被刪除。

注意到此JSON命令中的類型是 add 而不是 update , 因而當 doc 的主鍵沒有對應記錄存在時, solr會將 doc 內容作為一條新記錄插入:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update?commit=true' --data-binary '
{
  "add": {
    "doc": {
      "id": "0134685997",
      "author": "Joshua Bloch",
      "title": "Effective Java"
    }
  }
}'

當這條操作執行完后,會新增一條文檔 0134685997

進一步的,當此JSON命令中如果存在多個 add 節點,則可以同時對多條文檔記錄進行覆寫操作。

原子更新(atomic update)

solr還提供另外一種修改文檔的方式,原子修改(atomic update)。這種方式可以修改文檔中指定的字段,而不需要提供完整的文檔對象。

使用原子更新,solr core的配置需要滿足以下條件

  1. schema中包含 _version_字段
  2. solrconfig.xml 配置文件中包含 updateLog 配置項

這里,我們將 schema.xml 文件調整為:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Solr managed schema - automatically generated - DO NOT EDIT -->
<schema name="my" version="1.0">
  <uniqueKey>id</uniqueKey>
  <fieldType name="string" class="solr.StrField" sortMissingLast="true"/>
  <fieldType name="long" class="solr.LongPointField" omitNorms="true"/>
  <field name="_version_" type="long" indexed="true" stored="true" multiValued="false"/>
  <field name="author" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
  <field name="title" type="string" indexed="true" required="true" stored="true" multiValued="false"/>
  <field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>
  <field name="tags" type="string" multiValued="true" indexed="true" stored="true"/>
</schema>

solrconfig.xml 文件中添加 updateHandlerupdateLog 配置項:

<config>
  <luceneMatchVersion>8.2.0</luceneMatchVersion>
  <updateHandler>
    <updateLog>
      <str name="dir">${solr.ulog.dir:}</str>
    </updateLog>
  </updateHandler>
</config>

原子更新提供多種操作,這里演示設置一個字段,向一個數組類型的字段添加和刪除元素的操作:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update?commit=true' --data-binary '
[
  {
    "id": "0132350882",
    "title": { "set": "Clean Code" },
    "tags": {
      "add": "Computer Science",
      "remove": "Software Testing"
    }
  }
]'

注意,無論是要修改一個還是多個文檔,JSON數據的根節點都必須是一個數組,否則solr會當作覆寫操作來解析。 id 用來定位要修改的文檔。 title節點中的 set 表示將title字段修改為指定值。 tags 節點有兩個操作, addremove ,分別表示將 Computer Science 元素添加到 tags 數組中,將 Software Testing 元素從 tags 數組中刪除。此例中addremove 對應的值是單個元素,它們也可以接受數組值,用來表示同時插入或者刪除多個值。

刪除文檔

根據主鍵刪除文檔

刪除文檔的基本方式是根據文檔主鍵刪除指定文檔:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update?commit=true' --data-binary '
{
  "delete": { "id": "0132350882" }
}'

id節點的值可以也可以是一個數組,用來指定多個要刪除的文檔主鍵。注意,這里只能使用主鍵字段,而不能使用其他字段來匹配要刪除的文檔。

根據查詢條件刪除文檔

如果需要根據查詢條件刪除所有的匹配文檔,通過 query 來指定匹配條件。比如要刪除所有 tags 中含有 Computer Programming Languages 的文檔:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update?commit=true' --data-binary '
{
  "delete": { "query": "tags:\"Computer Programming Languages\"" }
}'

以下請求則會刪除所有的文檔:

curl -X POST -H 'Content-Type: application/json' 'http://localhost:8983/solr/my_core/update?commit=true' --data-binary '
{
  "delete": { "query": "*:*" }
}'

數據導出和還原

solr提供數據快照功能來實現數據的導出和還原。

數據導出

通過類似以下請求來創建一個數據快照:

curl 'http://localhost:8983/solr/my_core/replication?command=backup'

這個請求比前文中的其他請求都要簡單,而且這里使用的是GET請求。實際上GET和POST請求都是可以的。

這個請求只是觸發了創建快照的操作,而不會同步等待快照創建完成。當數據比較多的時候,快照可能會需要比較長的時間才能完成。此時,可以通過以下請求來查看快照創建的處理狀態:

curl 'http://localhost:8983/solr/my_core/replication?command=details'

同樣的,使用GET或者POST請求的效果是相同的。

solr在收到創建快照請求后,會在core的數據目錄下創建一個名為 snapshot.<yyyyMMddHHmmssSSS> 目錄,用來保存快照數據。比如在 /var/solr/data/my_core/data 目錄下會有類似 snapshot.20191203092949307 這樣快照目錄。

數據恢復

有了數據快照之后,就可以將數據恢復到快照保存的狀態了。

執行類似以下操作就可以恢復數據:

curl  'http://localhost:8983/solr/my_core/replication?command=restore'

同樣,恢復操作也是異步的,可以通過以下操作來查看恢復操作的狀態:

curl 'http://localhost:8983/solr/my_core/replication?command=restorestatus'

solr在收到數據恢復請求之后,會在core的數據目錄下查找命名格式為 snapshot.<yyyyMMddHHmmssSSS> 的目錄,然后使用目錄名后綴的時間最大的快照來進行數據恢復。

參考文檔

此文中只簡單介紹了solr數據的基本操作,這些操作還有很多其他的參數和用法,而且還有很多其他的操作。這些操作可以參考solr的官方文檔。文中的例子是基於solr 8.2版本的,最新版本的solr的操作會有不同,下面列出的都是solr 8.2的文檔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM