0

编辑:将我当前的查询添加到末尾

我有一个大型的人名数据库,并且正在使用弹性搜索(通过 symfony2 的 FOSElasticaBundle 和 Elastica)来更智能地搜索人名。

我有一个全名字段,我想用标准、ngram 和语音分析器对人名进行索引。

我已经在弹性搜索中设置了分析器,我可以开始将数据转储到索引中。我想知道我在这里做的方式是否是最好的方式,或者我是否可以将分析器应用于单个字段......我问的原因是因为当我执行 get /website/person/:id ,我在纯文本中看到所有三个字段...我期待在这里看到分析的数据,尽管我猜它必须只存在于倒排索引中而不是文档中。我见过的示例使用多个字段,但是否可以将多个分析器添加到单个字段?

我的 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"
          }
        }
      }
    }
  }
}

当我获取文档时,我看到所有三个字段都以纯文本形式存储......也许我需要为这些额外的字段设置 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;
4

1 回答 1

1

不,您不能在一个字段上拥有多个分析器。您正在做的方式是通过为同一字段设置不同的字段名称来应用多个分析器的正确方法。

您在 _source 字段中获得namePhoneticnameNgram的原因是使用

"store" : true

它告诉 ElasticSearch 您还需要这些额外的字段作为响应。利用

"store" : false

这将解决您的问题。

如果要查看某个字段的分析数据,可以使用 elasticsearch 的 _analyze api。

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-analyze.html

是的,这些字段在分析后存储在倒排索引中。

我希望我已经回答了你所有的疑问。如果您需要更多帮助,请告诉我。

谢谢

于 2014-07-13T16:44:24.117 回答