2012-03-02 19 views
7

Digamos que tengo el siguiente mapeo:¿Es posible clasificar documentos anidados en ElasticSearch?

"site": { 
    "properties": { 
    "title":  { "type": "string" }, 
    "description": { "type": "string" }, 
    "category": { "type": "string" }, 
    "tags":  { "type": "array" }, 
    "point":  { "type": "geo_point" } 
    "localities": { 
     type: 'nested', 
     properties: { 
     "title":  { "type": "string" }, 
     "description": { "type": "string" }, 
     "point":  { "type": "geo_point" } 
     } 
    } 
    } 
} 

estoy haciendo entonces una especie "_geo_distance" en el documento padre y soy capaz de ordenar los documentos sobre "site.point". Sin embargo, también me gustaría que las ubicaciones anidadas se clasifiquen por "_geo_distance", dentro del documento principal.

¿Esto es posible? ¿Si es así, cómo?

Respuesta

9

Desafortunadamente, no hay (al menos por ahora).

una consulta en Elasticsearch simplemente identifica los documentos que coinciden con la consulta, y lo bien que coinciden.

Para entender lo que anidan documentos son útiles para, considere este ejemplo:

{ 
    "title": "My post", 
    "body":  "Text in my body...", 
    "followers": [ 
     { 
      "name":  "Joe", 
      "status": "active" 
     }, 
     { 
      "name":  "Mary", 
      "status": "pending" 
     }, 
    ] 
}   

El JSON anterior, una vez indexadas en ES, es funcionalmente equivalente a la siguiente. Tenga en cuenta cómo el campo followers se ha aplanado:

{ 
    "title":   "My post", 
    "body":    "Text in my body...", 
    "followers.name": ["Joe","Mary"], 
    "followers.status": ["active","pending"] 
}   

Una búsqueda para: followers with status == active and name == Mary coincidiría con este documento ... incorrectamente.

campos anidados nos permiten trabajar alrededor de esta limitación. Si el campo followers se declara de tipo nested en lugar de tipo object a continuación su contenido se crean como un (invisible) sub-documento separado internamente. Eso significa que podemos usar un nested query o nested filter para consultar estos documentos anidados como documentos individuales.

Sin embargo, la salida de las cláusulas de consulta/filtro anidados sólo nos dice si el documento principal coincide, y lo bien que le corresponda. Ni siquiera nos dice cuál de los documentos anidados coincide. Para resolverlo, tendríamos que escribir código en nuestra aplicación para verificar cada uno de los documentos anidados según nuestros criterios de búsqueda.

hay algunas open issues que solicita la adición de estas características, pero no es un problema fácil de resolver.

La única manera de lograr lo que desea es indexar sus documentos secundarios como documentos separados y consultarlos y ordenarlos de forma independiente. Puede ser útil establecer una relación padre-hijo entre el documento principal y estos sub-documentos separados. (Ver parent-type mapping, la sección infantil de Padres & del index api docs, y los top-children y has-child consultas.

Además, un usuario ES ha enviado la lista de una nueva has_parent filter que están trabajando actualmente en un fork. Sin embargo, esta no está disponible en el repositorio ES principal todavía.

+0

Gracias por su excelente respuesta! – Yeggeps

+0

Ok, así que jugué un poco con esto. ¿De hecho, no hay forma de buscar por localidades en los campos parentales como yo lo veo? luego debe incluir el campo principal que debe poder buscarse en cada niño, ¿no? – Yeggeps

+0

Correcto. No se pueden hacer uniones. Cada documento se evalúa por sí mismo erits. Las consultas padre/hijo y anidadas duplican el trabajo porque primero ejecutan una consulta en (por ejemplo) los hijos, luego utilizan esos valores para ejecutar una consulta en contra de los padres – DrTech

Cuestiones relacionadas