Solrを導入とコア作成までは以下で実施する
- https://qiita.com/junk1400/items/b191750f72caf7138e83
- コアの名前はtestとする
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'
postでschemaを設定する場合、coreのリロードが必要なく即時反映される
管理画面でschemaが設定されたことを確認する
http://127.0.0.1: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'
管理画面で投入したデータを確認する
投入したデータを検索してみる
もう一度同じjsonを投入してみる
$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'
管理画面で投入したデータを確認する
- データが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'
デフォルトで検索してみる。
http://127.0.0.1:8983/solr/test/select?df=item_def&q=%E7%95%B0%E4%B8%96%E7%95%8C結果は0件になる
理由:新しいフィールドに対してindexの作成をしていないため
jsonでデータを入れ直す
$ curl 'http://localhost:8983/solr/test/update?commit=true&indent=true' --data-binary @prd_data.json -H 'Content-Type: text/json'
デフォルトで検索可能になる
「ロクサーヌ」では引っかかるが「ロク」では引っかからない件
*「ロクサーヌ」で検索をすると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
- 原因は、商品説明に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で検索する
- どちらも検索できる。
- 形態素とngramはどちらが良いではなく、組み合わせて使うのが良い
- 形態素、ngramともに特性を理解して使用しないと検索結果や検索順位に多大な影響を及ぼす
- 前はhitしたのにちょっと変更しただけで、hitしなくなった等等
memo
インデックスのデータをすべて削除
$ curl -H 'Content-Type: application/json' 'http://localhost:8983/solr/test/update?commit=true' -d '{ delete: { query: "*:*" }}'