Help us understand the problem. What is going on with this article?

solrにschema設定してデータをpostする

More than 1 year has passed since last update.

Solrを導入とコア作成までは以下で実施する

schemaを考える(簡易版)

  • 簡易スキーマーを下記とする
name type stored indexed multivalued
item_id string true true false
isbn string true true false
item_nm text_ja true true false
item_yomi text_ja true true false
item_cls pint true true false
cont_intr text_ja true true false
price ping true true false
sls_st_dttm pdate true true false
sls_ed_dttm pdate true true false

schema add field

  • 以下のPOSTでスキーマーを設定する
curl -X POST -H 'Content-type:application/json' --data-binary '{
    "add-field": [
        {
            "name": "item_id",
            "type": "string",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "isbn",
            "type": "string",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "item_nm",
            "type": "text_ja",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "item_yomi",
            "type": "text_ja",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "item_cls",
            "type": "pint",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "cont_intr",
            "type": "text_ja",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "price",
            "type": "pint",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "sls_st_dttm",
            "type": "pdate",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        },
        {
            "name": "sls_ed_dttm",
            "type": "pdate",
            "stored": true,
            "indexed": true,
            "multiValued": false,
        }
    ]
}' 'http://localhost:8983/solr/test/schema'

jsonでデータを投入する

投入するjson

prd_data.json
[
  {
    "item_id" : "001",
    "isbn" : "9784041062050",
    "item_nm" : "異世界迷宮でハーレムを(1)",
    "item_yomi" : "いせかいめいきゅうではーれむを",
    "item_cls" : 1,
    "cont_intr" : "怪しげなウェブサイトでゲームキャラメイクをしたら何故か異世界で目覚めた道夫。しかしその世界の「奴隷」制度を知った道夫はゲーム設定時
に獲得したスキルを使い夢のハーレム生活を送るため冒険に出るのだった!",
    "price" : 626,
    "sls_st_dttm" : "2018-01-01"
  }
,
  {
    "item_id" : "002",
    "isbn" : "9784041067215",
    "item_nm" : "異世界迷宮でハーレムを(2)",
    "item_yomi" : "いせかいめいきゅうではーれむを",
    "item_cls" : 1,
    "cont_intr" : "迷宮探索・盗賊退治と命懸けで金策した道夫は、ついに「ロクサーヌ」購入資金を手に入れる。再び商館を訪れた道夫は無事「ロクサーヌ」の所
有者となり、初夜を迎えるべく自分の宿に向かうのだった!?",
    "price" : 626,
    "sls_st_dttm" : "2018-01-01"
  }
]
  • 以下のコマンドで投入する
$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'

管理画面で投入したデータを確認する

http://127.0.0.1:8983/solr/#/test/query

投入したデータを検索してみる

http://127.0.0.1:8983/solr/test/select?q=item_nm:%E7%95%B0%E4%B8%96%E7%95%8C

もう一度同じjsonを投入してみる

$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'

管理画面で投入したデータを確認する

http://127.0.0.1:8983/solr/#/test/query

  • データが4件に増えていることが確認できる
  • 理由はuniquekeyがidになっていてitem_idがuniquekeyではないため

uniquekeyを設定する

インデックスのデータをすべて削除

  • 一旦インデックスのデータを削除します
$ curl -H 'Content-Type: application/json' 'http://localhost:8983/solr/test/update?commit=true' -d '{ delete: { query: "*:*" }}'

uniquekeyを設定

  • managed-schemaファイルにあるuniquekeyを変更します
vim /data/test/conf/managed-schema

<uniqueKey>id</uniqueKey>
            ↓
<uniqueKey>item_id</uniqueKey>

  • idフィールドは使用しないので削除します
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "delete-field" : { "name":"id" }
}' http://localhost:8983/solr/test/schema

コンテナ再起動

  • uniquekeyの設定をmanaged-schemaファイルを開いて行ったため、コンテナの再起動をする
$ sudo docker restart solr_solr_1
  • uniquekey確認
$ curl http://localhost:8983/solr/test/schema/uniquekey?wt=json

jsonを投入してみる

$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'

同じjsonを再度投入してみる

$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'
  • versionだけが上がっていることが確認できる

デフォルトサーチフィールド

The Default Search Field

  • defaultsearchfieldについて、昔のバージョンではschema.xmlに defaultsearchfield を指定することで、項目指定をしなかった場合にデフォルト項目への検索を実行してくれていたが、Solr7はschemaにdefaultsearchfieldがあるとexceptionを出すようになった。(らしい)
  • 代わりにリクエストパラメータで、dfでフィールドを指定する事

デフォルトサーチ用フィールド作成

デフォルト検索で、商品名、商品名かな、商品説明を検索するようにするには、

  • それ用のフィールドを用意(item_defという名前のフィールドを追加します)し、値をコピーフィールドでコピーします
  • コピーフィールドでフィルド値をデフォルトサーチフィールド用にコピーすることで登録用のスキーマーを変更せず対応できる
curl -X POST -H 'Content-type:application/json' --data-binary '{
    "add-field": [
        {
            "name": "item_def",
            "type": "text_ja",
            "stored": true,
            "indexed": true,
            "multiValued": true,
            "required" : true,
        }
    ]
}' 'http://localhost:8983/solr/test/schema'
  • デフォルトサーチフィールドで検索したい項目をコピーフィールドで設定する
  • 商品名、ヨミ、商品説明を1つのフィールドにコピーする
curl -X POST -H 'Content-type:application/json' --data-binary '{
    "add-copy-field": [
        {
            "source":"item_nm",
            "dest": "item_def"
        },
        {
            "source":"item_yomi",
            "dest": "item_def"
        },
        {
            "source":"cont_intr",
            "dest": "item_def"
        }
    ]
}' 'http://localhost:8983/solr/test/schema'

jsonでデータを入れ直す

$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'

デフォルトで検索可能になる

http://127.0.0.1:8983/solr/test/select?df=prd_def&q=%E7%95%B0%E4%B8%96%E7%95%8C

「ロクサーヌ」では引っかかるが「ロク」では引っかからない件

*「ロクサーヌ」で検索をすると1件hitするが「ロク」で検索すると1件もhitしない
http://127.0.0.1:8983/solr/test/select?df=item_def&q=%E3%83%AD%E3%82%AF%E3%82%B5%E3%83%BC%E3%83%8C

http://127.0.0.1:8983/solr/test/select?df=item_def&q=%E3%83%AD%E3%82%AF

  • 原因は、商品説明にtext_jaを使っており、text_jaが形態素のため名詞「ロクサーヌ」と名詞「ロク」は別物としてhitしない。
  • この商品説明の「ロクサーヌ」を「ロク」でhitさせようとする場合、いくつか方法があるが今回はngramを併用する方法を取る

schemaにngram用のフィールドタイプを追加する

  • ngram追加(バイグラム)
curl -X POST -H 'Content-type:application/json' --data-binary '{
  "add-field-type" : {
     "name":"text_2gram",
     "class":"solr.TextField",
     "positionIncrementGap":"100",
     "autoGeneratePhraseQueries":"true",
     "analyzer" : {
        "tokenizer":{
           "class":"solr.NGramTokenizerFactory",
           "minGramSize":"2",
           "maxGramSize":"2"}}}
}' 'http://localhost:8983/solr/test/schema'

ngramのフィールドを追加し、コピーフィールドを設定する

curl -X POST -H 'Content-type:application/json' --data-binary '{
    "add-field": [
        {
            "name": "item_def_ngram",
            "type": "text_2gram",
            "stored": true,
            "indexed": true,
            "multiValued": true,
            "required" : true,
        }
    ]
}' 'http://localhost:8983/solr/test/schema'

curl -X POST -H 'Content-type:application/json' --data-binary '{
    "add-copy-field": [
        {
            "source":"item_nm",
            "dest": "item_def_ngram"
        },
        {
            "source":"item_yomi",
            "dest": "item_def_ngram"
        },
        {
            "source":"cont_intr",
            "dest": "item_def_ngram"
        }
    ]
}' 'http://localhost:8983/solr/test/schema'

jsonでデータを入れ直す

  • schemaに新しい項目を追加したらindexを作り直す
$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'

ngramで検索する

http://127.0.0.1:8983/solr/test/select?df=item_def_ngram&q=%E3%83%AD%E3%82%AF%E3%82%B5%E3%83%BC%E3%83%8C

http://127.0.0.1:8983/solr/test/select?df=item_def_ngram&q=%E3%83%AD%E3%82%AF

  • どちらも検索できる。
  • 形態素とngramはどちらが良いではなく、組み合わせて使うのが良い
  • 形態素、ngramともに特性を理解して使用しないと検索結果や検索順位に多大な影響を及ぼす
  • 前はhitしたのにちょっと変更しただけで、hitしなくなった等等

memo

インデックスのデータをすべて削除

$ curl -H 'Content-Type: application/json' 'http://localhost:8983/solr/test/update?commit=true' -d '{ delete: { query: "*:*" }}'
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away