将自定义分析仪应用于具有弹性搜索的字段的正确方法,使用单个分析仪将多个分析仪应用于一个字段或多个字段?

时间:2014-07-13 16:09:00

标签: symfony elasticsearch foselasticabundle

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

我有一个庞大的人名数据库,我正在使用弹性搜索(通过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;

1 个答案:

答案 0 :(得分:1)

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

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

"store" : true

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

"store" : false

这将解决您的问题。

如果您想在字段上查看分析数据,可以使用弹性搜索的_analyze api。

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

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

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

由于