CLOVER🍀

That was when it all began.

Apache Solrで、ユニークキーをAnalyzeしているとユニークにならない時があるという話

たまたまスキーマ定義がそうなってて、ちょっとハマったのでメモ。

Apache Solrのユニークキーで使用するフィールドですが、この値が重複しているはずなのにドキュメントがユニークにならなくて困ったという話です。

schema.xmlは、以下とします。

    <field name="id" type="text_ja" indexed="true" stored="true" required="true" multiValued="false" />

  <uniqueKey>id</uniqueKey>

「_version_」などは省略します。「text_ja」はKuromojiを使った形態素解析フィールドとします。

このコアに対して、以下のようにデータを放り込みます。

$ curl -XPOST -H 'Content-Type: application/json' http://localhost:8983/solr/mycore/update?commit=true -d '[{ "id": "あいうえお" }, { "id": "あいうえお" }, { "id": "abc" }, { "id": "abc" }, { "id": "cd e" }, { "id": "cd e" }]'

idはユニークキーですが、「あいうえお」「abc」「cd e」をそれぞれ2つずつ登録します。

クエリ実行。

$ curl 'http://localhost:8983/solr/mycore/select?wt=json&indent=true&q=*:*'{
  "responseHeader":{
    "status":0,
    "QTime":2,
    "params":{
      "q":"*:*",
      "indent":"true",
      "wt":"json"}},
  "response":{"numFound":5,"start":0,"docs":[
      {
        "id":"あいうえお",
        "_version_":1521548085400961024},
      {
        "id":"あいうえお",
        "_version_":1521548085403058176},
      {
        "id":"abc",
        "_version_":1521548085404106753},
      {
        "id":"cd e",
        "_version_":1521548085405155328},
      {
        "id":"cd e",
        "_version_":1521548085405155329}]
  }}

なんと、ユニークキーなのに同じ値を持つドキュメントが登録されています…。

ここで、フィールドタイプを「text_ja」ではなく「string」にしてみます。

1度データを削除して

$ curl -XPOST -H 'Content-Type: application/json' http://localhost:8983/solr/mycore/update?commit=true -d '{ "delete": { "query": "*:*" } }'
{"responseHeader":{"status":0,"QTime":21}}

定義変更。

    <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />

コアをリロード。

$ curl 'http://localhost:8983/solr/admin/cores?action=RELOAD&core=mycore'
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">179</int></lst>
</response>

もう1度データ登録。

$ curl -XPOST -H 'Content-Type: application/json' http://localhost:8983/solr/mycore/update?commit=true -d '[{ "id": "あいうえお"  }, { "id": "あいうえお" }, { "id": "abc" }, { "id": "abc" }, { "id": "cd e" }, { "id": "cd e" }]'
{"responseHeader":{"status":0,"QTime":53}}

検索。

$ curl 'http://localhost:8983/solr/mycore/select?wt=json&indent=true&q=*:*'{
  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "q":"*:*",
      "indent":"true",
      "wt":"json"}},
  "response":{"numFound":3,"start":0,"docs":[
      {
        "id":"あいうえお",
        "_version_":1521548611081469952},
      {
        "id":"abc",
        "_version_":1521548611082518529},
      {
        "id":"cd e",
        "_version_":1521548611082518531}]
  }}

今度は、ユニークになりました。

通常、ユニークキーはAnalyzeしないフィールドタイプを選ぶような気がしますが、自分の時はたまたまAnalyzeするフィールドがいて、この事象にハマりました…。

これ、SolrというよりはLuceneの挙動では?と思うのですが、どうなのかな。まあ、いずれにせよ今後は意識しておくことにします。