編集:現在のクエリを最後に追加しました
私は人間の名前の大規模なデータベースを持っており、(symfony2 の FOSElasticaBundle と Elastica を介して) エラスティック検索を使用して、名前をよりスマートに検索しています。
氏名フィールドがあり、標準、ngram、および音声アナライザーを使用して人々の名前にインデックスを付けたいと考えています。
エラスティック検索でアナライザーをセットアップしました。これで、インデックスへのデータのダンプを開始できます。ここで行っている方法が最善の方法なのか、それともアナライザーを単一のフィールドに適用できるのか疑問に思っています...私が尋ねる理由は、 get /website/person/:id を実行するときだからです、プレーン テキストで 3 つのフィールドがすべて表示されます...ここで分析されたデータが表示されることを期待していましたが、ドキュメントではなく転置インデックスにのみ存在する必要があると思います。私が見た例では複数のフィールドを使用していますが、単一のフィールドに複数のアナライザーを追加することは可能ですか?
私のconfig.yml:
fos_elastica:
clients:
default: { host: %elastica_host%, port: %elastica_port% }
indexes:
website:
settings:
index:
analysis:
analyzer:
phonetic_analyzer:
type: "custom"
tokenizer: "lowercase"
filter: ["name_metaphone", "lowercase", "standard"]
ngram_analyzer:
type: "custom"
tokenizer: "lowercase"
filter : [ "name_ngram" ]
filter:
name_metaphone:
encoder: "metaphone"
replace: false
type: "phonetic"
name_ngram:
type: "nGram"
min_gram: 2
max_gram: 4
client: default
finder: ~
types:
person:
mappings:
name: ~
nameNGram:
analyzer: ngram_analyzer
namePhonetic:
analyzer: phonetic_analyzer
マッピングを確認すると、良さそうです。
{
"website" : {
"mappings" : {
"person" : {
"_meta" : {
"model" : "acme\\websiteBundle\\Entity\\Person"
},
"properties" : {
"name" : {
"type" : "string",
"store" : true
},
"nameNGram" : {
"type" : "string",
"store" : true,
"analyzer" : "ngram_analyzer"
},
"namePhonetic" : {
"type" : "string",
"store" : true,
"analyzer" : "phonetic_analyzer"
}
}
}
}
}
}
ドキュメントを GET すると、3 つのフィールドすべてがプレーン テキストで保存されていることがわかります。おそらく、これらの追加フィールドに STORE: FALSE を設定する必要がありますか、それとも適切に分析されていませんか?
{
"_index" : "website",
"_type" : "person",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source":{
"name":"John Doe",
"namePhonetic":"John Doe",
"nameNGram":"John Doe"
}
}
編集:私が現在使用しているソリューションは、まだいくつかの改良が必要ですが、ほとんどの名前でうまくテストされています
//Create the query object
$boolQuery = new \Elastica\Query\Bool();
//Boost exact name matches
$exactMatchQuery = new \Elastica\Query\Match();
$exactMatchQuery->setFieldParam('name', 'query', $name);
$exactMatchQuery->setFieldParam('name', 'boost', 10);
$boolQuery->addShould($exactMatchQuery);
//Create a basic Levenshtein distance query
$levenshteinMatchQuery = new \Elastica\Query\Match();
$levenshteinMatchQuery->setFieldParam('name', 'query', $name);
$levenshteinMatchQuery->setFieldParam('name', 'fuzziness', 1);
$boolQuery->addShould($levenshteinMatchQuery);
//Create a phonetic query, seeing if the name SOUNDS LIKE the name that was searched
$phoneticMatchQuery = new \Elastica\Query\Match();
$phoneticMatchQuery->setFieldParam('namePhonetic', 'query', $name);
$boolQuery->addShould($phoneticMatchQuery);
//Create an NGRAM query
$nGramMatchQuery = new \Elastica\Query\Match();
$nGramMatchQuery->setFieldParam('nameNGram', 'query', $name);
$nGramMatchQuery->setFieldParam('nameNGram', 'boost', 2);
$boolQuery->addMust($nGramMatchQuery);
return $boolQuery;