2012-02-05 12 views
5

Digamos que tengo una colección en mongodb cuyos objetos tienen una matriz anidada. Quiero ordenar en función del valor de un elemento particular de la matriz. es posible?¿Puedo ordenar por un elemento dentro de una matriz anidada en Mongo?

Por ejemplo (y acabo de hacer el ejemplo), si tengo una colección de tipos de películas (acción, comedia, romance) y ejemplos enviados por los usuarios, ¿puedo encontrar todos los objetos donde se envió un usuario determinado ordenado por el fecha de la película?

Por ejemplo, me gustaría encontrar todos los tipos en los que 'Aaron' presentó un ejemplo, ordenado por el año del ejemplo 'Aaron' enviado.

Es casi como una necesidad donde la cláusula en el género.

> db.movies.find(). Pretty();

{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 

> db.movies.find ({ 'examples.submitter': 'Aaron'}) tipo.. ({ 'Examples.year': 1}) bastante();

{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 

Nota los documentos se devuelven ordenados por la colecciones años (como se esperaba) - cualquier forma de ordenar con sólo las presentadas por un determinado usuario? para algunos detalles adicionales, estoy usando el controlador mongo nativo del nodo para nodejs.

Respuesta

5

... ¿alguna forma de ordenar por las enviadas por un usuario determinado?

No creo que esto vaya a funcionar como usted desea.

En MongoDB, las consultas devuelven documentos completos. Cuando realiza la siguiente consulta, está encontrando todos los documentos donde cualquier remitente coincide con 'Aaron'.

> db.movies.find({'examples.submitter': 'Aaron'}) 

Tenga en cuenta que en teoría podría coincidir 'Aaron' dos veces en el mismo documento, pero sólo devolver ese documento una vez. Esto complica el problema de clasificación.

> db.movies.find({'examples.submitter': 'Aaron'}).sort({'examples.year': 1}) 

Entonces, ¿qué se puede esperar cuando un documento contiene dos cosas por 'Aaron' con diferentes años? Recuerde que solo podemos ordenar los documentos, no podemos ordenar el conjunto interno con la consulta.

El problema aquí es que estás usando "matrices de objetos" lo que complica todo el proceso. Su pregunta de clasificación supone que podemos actuar sobre los objetos internos y realmente no podemos.

Por favor, eche un vistazo a la nueva Aggregation Framework que puede proporcionar lo que está buscando. Tenga en cuenta que esto es actualmente una característica en la rama inestable.

+0

No pensé que sería capaz de hacerlo, pero pensé que valía la pena intentarlo. Me alegro de haberlo mencionado, ya que el Marco de Agregación que mencionas parece que podría llevarme allí una vez listo/estable. ¡Gracias! – Zugwalt

0

Para su caso, tendrá que usar eval y hacer la clasificación personalizada en el server side. Eche un vistazo a here para obtener un ejemplo específico de clasificación. Su función de comparación será un poco más compleja, ya que tendrá que pasar a través de una matriz de "ejemplos" y filtrar por el remitente.

1

En caso de que alguien se tropieza demás sobre esto, yo era capaz de resolver un problema similar mediante la creación de un índice como:

{'examples.submitter': 1, 'examples.year': 1} 

Si fuerza su consulta para utilizar este índice usando indirecta ("indexname"), sus resultados volverán en orden del índice.

+0

¿Podría dar más detalles sobre dónde coloca ese archivo/cómo funciona? También estoy luchando con un problema muy similar al de aquí. – ritmatter

+1

Necesita usar .ensureIndex en su colección. Usualmente haces esto con un mongo db ide o en la línea de comando. http://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/ Para la sugerencia, puede usar mongodb http://docs.mongodb.org/manual/reference/operator/meta/hint/ o con mangosta use la función de sugerencia en su consulta. query.hint ({indexA: 1, indexB: -1}) –

Cuestiones relacionadas