symfony - index - join queries elastic
Cómo realizar consultas anidadas con Elastica Search y Symfony2 (2)
Aquí hay una respuesta de cómo hacerlo. Para mi funciona http://obtao.com/blog/2014/04/elasticsearch-advanced-search-and-nested-objects/
Básicamente, necesitas crear una consulta como esa:
{
"query":{
"filtered":{
"query":{
"query_string":{
"query":"*saf*"
}
},
"filter":{
"nested":{
"path":"categories",
"filter":{
"bool":{
"must": [{
"term":{
"categories.id":1
}
}]
}
},
"query":{
"match":{
"id":1
}
}
}
}
}
}
}
Para mí en PHP parece:
$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);
El filtro es Elastica / Filter y Query es Elastica / Query
Tengo una entidad de recetas que tiene algunas etiquetas (asignación de muchas a muchas) y quiero buscar recetas por etiquetas.
Aquí está mi entidad de Receta:
/**
* @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;
Aquí está mi configuración:
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: ~
Luego agregué un repositorio personalizado para realizar búsquedas:
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);
}
Luego busco de esta manera:
$repositoryManager = $this->get(''fos_elastica.manager.orm'');
$repository = $repositoryManager->getRepository(''ckRecipesBundle:Recipe'');
$recipes = $repository->filterFind(''mytag'');
Pero no obtuve ningún resultado a pesar del hecho de que hay resultados que coinciden.
No encontré ninguna respuesta en google. Alguien puede ayudarme ?
De hecho, olvidaste definir la consulta filtrada.
Esto debería funcionar :
$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);