ElasticSearch如何通过2级嵌套项搜索?

时间:2016-11-07 10:44:34

标签: symfony elasticsearch foselasticabundle

我有这种数据结构

[
    {
        id:1,
        translations: [
           {
               language: {id:1; name: "English"},
               value: "How are you ?"
           },
           {
               language: {id:2; name: "French"},
               value: "Comment allez-vous ?"
           },
           ...
        ]
    },
    ...
]

所以现在我想做一个只能用英文翻译而不是用法语或其他语言搜索单词的查询。如果用户输入“Comment allez-vous”,他将看不到任何结果。

这里是config.yml

        index_name: %es.index_name%
        types:
            vocabularyItem:
                mappings:
                    translations:
                        type: "nested"
                        properties:
                            value: {boost: 5}
                            definition: {boost: 2}
                            alternativeTranslations:
                                type: "nested"
                                properties:
                                    value: ~
                            language:
                                type: "nested"
                                properties:
                                    id:
                                        type : integer
                persistence:
                    driver: orm
                    model: Bundle\Model\VocabularyItem
                    provider:
                        batch_size: 100
                    listener:
                        immediate: ~
                    finder: ~

1 个答案:

答案 0 :(得分:0)

首先,我建议您使用自定义存储库。这只是一个女巫搜索功能。这对于保持控制器清洁非常有用。

在你的弹性配置中:

types:
    vocabularyItem:
        mappings:
            ...
        persistence:
            ...
            repository: AppBundle\SearchRepository\VocabularyItemRepository

然后在您的控制器中(假设您的索引的名称是app)

$vocabularyItemRepo = $this->get('fos_elastica.repository_manager')->getRepository('app/vocabularyItem');
$results = $vocabularyItemRepo->searchEnglish($keywords);

最后是有趣的部分,带有查询的存储库

<?php

namespace AppBundle\SearchRepository;

use FOS\ElasticaBundle\Repository;
... //other use

class VocabularyItemRepository extends Repository
{
    public function searchEnglish($keywords)
    {
        $query = new BoolQuery();

        $englishQuery = new Match();
        $englishQuery->setField('translations.language.name', 'English');
        $query->addMust($englishQuery);

        $keywordsQuery = new Match();
        $keywordsQuery->setField('yourKeyWordField', $keywords);
        $query->addMust($keywordsQuery);

        return $this->find($query);
    }
}

请尝试这个并告诉我是否有问题