【问题标题】:How to perform nested queries with Elastica Search and Symfony2如何使用 Elastica Search 和 Symfony2 执行嵌套查询
【发布时间】:2014-08-14 12:29:10
【问题描述】:

我有一个带有一些标签(多对多映射)的食谱实体,我想按标签搜索食谱。

这是我的食谱实体:

/**
 * @ORM\Entity
 * @ORM\Table(name="recipes")
 * @ORM\HasLifecycleCallbacks
 * @ExclusionPolicy("all")
 */
class Recipe
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Expose
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=150)
     * @Expose
     */
    protected $name;

    ...

    /**
     * @ORM\ManyToMany(targetEntity="RecipesTag", inversedBy="recipes")
     * @ORM\JoinTable(name="bind_recipes_tags",
     *      joinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="recipe_id", referencedColumnName="id")}
     *      )
     */
    private $tags;

这是我的配置:

fos_elastica:
    clients:
        default: { host: localhost, port: 9200 }
    serializer:
        callback_class: FOS\ElasticaBundle\Serializer\Callback
        serializer: serializer
    indexes:
        td:
            client: default
            types:
                Recipe:
                    mappings:
                        name: ~
                        ingredients: 
                            type: "nested"
                            properties:
                                name: ~
                        tags:
                            type: "nested"
                            properties:
                                name: ~
                                id : 
                                    type : integer
                        categories:
                            type: "nested"
                            properties:
                                name: ~
                                id : 
                                    type : integer

                    persistence:
                        driver: orm # orm, mongodb, propel are available
                        model:  ck\RecipesBundle\Entity\Recipe
                        repository: ck\RecipesBundle\Entity\RecipesRepository
                        provider: ~
                        listener: ~
                        finder: ~

然后我添加了一个自定义存储库来执行搜索:

public function filterFind($searchText)
{
    $query_part = new \Elastica\Query\Bool();

    $nested = new \Elastica\Query\Nested();
    $nested->setQuery(new \Elastica\Query\Term(array('name' => array('value' => $searchText))));
    $nested->setPath('tags');
    $query_part->addShould($nested);

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

然后我这样搜索:

$repositoryManager = $this->get('fos_elastica.manager.orm');
$repository = $repositoryManager->getRepository('ckRecipesBundle:Recipe');

$recipes = $repository->filterFind('mytag');

但尽管有匹配的结果,但我没有得到任何结果。

我在谷歌上没有找到任何答案。 任何人都可以帮助我吗?

【问题讨论】:

  • 你解决了吗?答案好吗?

标签: symfony elasticsearch mapping nested-queries


【解决方案1】:

这里是响应如何做到这一点。对我来说它有效。 http://obtao.com/blog/2014/04/elasticsearch-advanced-search-and-nested-objects/

基本上,您需要像这样创建查询:

{
    "query":{
        "filtered":{
            "query":{
                "query_string":{
                    "query":"*saf*"
                }
            },
            "filter":{
                "nested":{
                    "path":"categories",
                    "filter":{
                        "bool":{
                            "must": [{
                                "term":{
                                    "categories.id":1
                                }
                            }]
                        }
                    },
                    "query":{
                        "match":{
                            "id":1
                        }
                    }
                }
            }
        }
    }
} 

在 PHP 中对我来说是这样的:

        $bool = new Filter\Bool();
        $bool->addMust(new Filter\Term(['categories.id' => $category->getId()]));

        $nested = new Filter\Nested();
        $nested->setPath("categories");
        $nested->setFilter($bool);

        $nested->setQuery($categoriesQuery);

        $queryObj = new Query\Filtered($queryObj, $nested);

过滤器是 Elastica\Filter,查询是 Elastica\Query

【讨论】:

    【解决方案2】:

    确实,您忘记定义过滤查询。

    这应该有效:

    $nested->setQuery(new \Elastica\Query\Term(array('name' => array('value' => $searchText))));
    $nested->setPath('tags');
    $query_part->addShould($nested);
    
    $query = new \Elastica\Query\Filtered($query_part/*, $filters // in case you had other filters*/);
    return $this->find($query);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      相关资源
      最近更新 更多