[Solr] Nested Documents での部分更新

はじめに

以前はできなかった入れ子構造のドキュメントの部分的な更新が Solr 8.1 からはできるようになりました。この記事では入れ子構造のドキュメントの部分的な更新の動作を確認します。

更新前の状態

以下のプレイリストのデータを Solr に投入します。

[{
    "id":"list_1",
    "title_t":"list1",
    "songs":[
	{
	    "id":"l1!song1",
	    "title_t":"title1",
	    "artist_t":"artist1",
	    "trackNum_i":1
	},
	{
	    "id":"l1!song2",
	    "title_t":"title2",
	    "artist_t":"artist2",
	    "trackNum_i":2
	}
    ]
},
{
    "id":"list_2",
    "title_t":"list2",
    "songs":[
	{
	    "id":"l2!song1",
	    "title_t":"title3",
	    "artist_t":"artist3",
	    "trackNum_i":1
	},
	{
	    "id":"l2!song2",
	    "title_t":"title1",
	    "artist_t":"artist1",
	    "trackNum_i":2
	}
    ]
}
]

プレイリスト全体のデータで更新

以前はこのタイプの更新しかサポートされていませんでした。

$ cat update.json 
[{
    "id":"list_1",
    "title_t":"LIST1",
    "songs":[
	{
	    "id":"l1!song1",
	    "title_t":"TITLE1",
	    "artist_t":"ARTIST1",
	    "trackNum_i":1
	},
	{
	    "id":"l1!song2",
	    "title_t":"TITLE2",
	    "artist_t":"ARTIST2",
	    "trackNum_i":2
	}
    ]
}]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @update.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":90}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698469478122127360,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"TITLE1",
            "artist_t":"ARTIST1",
            "trackNum_i":1,
            "_version_":1698469478122127360},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698469478122127360}]}]
  }}

タイトルとアーティスト名を大文字にしてみました。

曲データだけを更新

_root_ フィールドで親ドキュメント(この場合プレイリストデータ)の id を指定します。

$ cat update2.json 
[
    {
	"id":"l1!song1",
	"_root_":"list_1",
	"title_t":{set:"title1"},
	"artist_t":{set:"artist1"}
    }
]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @update2.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":131}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698470257771937792,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"title1",
            "artist_t":"artist1",
            "trackNum_i":1,
            "_version_":1698470257771937792},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698470257771937792}]}]
  }}

l1!song1の曲名とアーティスト名を小文字に戻しました。

プレイリストに曲を追加

親ドキュメントの id を指定して、songs フィールドに対する add を実行します。

$ cat add.json 
[
    {
	"id":"list_1",
	"_root_":"list_1",
	"songs":{"add":{"id":"l1!song3",
		       "title_t":"title4",
		       "artist_t":"artist4",
		       "trackNum_i":3
		      }}
    }
]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @add.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":67}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698470937227165696,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"title1",
            "artist_t":"artist1",
            "trackNum_i":1,
            "_version_":1698470937227165696},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698470937227165696},
          
          {
            "id":"l1!song3",
            "title_t":"title4",
            "artist_t":"artist4",
            "trackNum_i":3,
            "_version_":1698470937227165696}]}]
  }}

プレイリスト list_1 に3曲目を追加しました。

プレイリストから曲を削除

親ドキュメントの id を指定して、songs フィールドに対する remove を実行します。

$ cat remove.json 
[
    {
	"id":"list_1",
	"_root_":"list_1",
	"songs":{"remove":{"id":"l1!song3"}}
    }
]
$ curl --user solr:SolrRocks 'http://localhost:8983/solr/nestedDocuments/update?commit=true&wt=json' --data-binary @remove.json -H 'Content-Type: application/json'
{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":50}}
$ curl -s 'http://localhost:8983/solr/nestedDocuments/select' -d 'omitHeader=true' --data-urlencode 'q={!parent which="id:list_1 -_nest_path_:*"}' -d 'fl=*,[child]'
{
  "response":{"numFound":1,"start":0,"numFoundExact":true,"docs":[
      {
        "id":"list_1",
        "title_t":"LIST1",
        "_version_":1698471464250900480,
        "songs":[
          {
            "id":"l1!song1",
            "title_t":"title1",
            "artist_t":"artist1",
            "trackNum_i":1,
            "_version_":1698471464250900480},
          
          {
            "id":"l1!song2",
            "title_t":"TITLE2",
            "artist_t":"ARTIST2",
            "trackNum_i":2,
            "_version_":1698471464250900480}]}]
  }}

先程追加した l1!song3 を削除しました。

コメント