Tengo una colección estructurada de este modo:

{
  _id: 1,
  score: [
    {
      foo: 'a',
      bar: 0,
      user: {user1: 0, user2: 7}
    }
  ]
}

Necesito encontrar todos los documentos que tienen al menos un ‘score’ (elemento de la puntuación de la matriz) que tiene un cierto valor de ‘bar’ y no está vacío ‘usuario’ sub-documento.

Esto es lo que se me ocurrió (y parecía que debería funcionar):

db.col.find({score: {"$elemMatch": {bar:0, user: {"$not":{}} }}})

Pero, me sale este error:

error: { "$err" : "$not cannot be empty", "code" : 13030 }

Cualquier otra manera de hacer esto?

  • Es que exactamente cómo se estructura? Parece un poco apagado. > var doc = { puntuación: [ foo: ‘a’, de la barra: 0, usuario: { usuario1: 0, usuario2: 7 } ] }; Jue Jul 7 00:43:42 SyntaxError: missing ] después de elemento de lista (shell):1
  • tienes razón, olvidé las llaves en el interior de la matriz.
InformationsquelleAutor Dmitri | 2011-07-07

4 Comentarios

  1. 66

    Descubierto: { 'score.user': { "$gt": {} } } coincidirá no vacío docs.

    • En este caso, score.user es un objeto. También trabajo para comprobar si score, una matriz está vacía?
    • Es posible, pero para las matrices usted está probablemente mejor usar: { foo: { $not: { $size: 0 } } }
    • excelente! He probado, y tanto trabajó. ¿Sabe usted por qué la segunda opción sería la mejor?
    • ¿Alguien puede explicar cómo esto está funcionando?
    • ver los documentos en orden: docs.mongodb.org/manual/reference/bson-types – un vacío doc se ordena antes que cualquier no-vacío doc, pero una nula voluntad de ordenar antes de cualquier (vacías) doc.
  2. 3

    No estoy seguro de entender su esquema, pero quizás la más sencilla sería la de no tener un valor «vacío» para puntuación.usuario ?

    Lugar a propósito no han dicho campo en el documento, si no tiene contenido?

    A continuación, la consulta podría ser algo así como …

    > db.test.find({ "score" : { "$elemMatch" : { bar : 0, "user" : {"$exists": true }}}})

    es decir, buscando un valor en puntuación.barra de que desee (0 en este caso) la comprobación de que el mear existencia ($existe, ver docs) de puntuación.usuario (y si tiene un valor, entonces va a existir?)

    editied: oops se me perdió el $elemMatch que tenía …

    • Sí, he pensado en hacerlo de esa manera, la principal razón por la que prefiere una consulta que coincida tanto inexistente y vacío user es que las puntuaciones de los usuarios puede ser eliminado y yo prefiero no tener que comprobar si el subdoc está vacío y debe ser eliminado todo el tiempo.
  3. 1

    Usted probablemente desea agregar un auxiliar de la matriz que realiza un seguimiento de los usuarios en el user documento:

    {
      _id: 1,
      score: [
        {
          foo: 'a',
          bar: 0,
          users: ["user1", "user2"],
          user: {user1: 0, user2: 7}
        }
      ]
    }

    A continuación, puede añadir nuevos usuarios de forma atómica:

    > db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},                       
    ... {$set: {'score.$.user.user3': 10}, $addToSet: {'score.$.users': "user3"}})

    Quitar usuarios:

    > db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},
    ... {$unset: {'score.$.user.user3': 1}, $pop: {'score.$.users': "user3"}})      

    Consulta de calificaciones:

    > db.test.find({_id: 1, score: {$elemMatch: {bar: 0, users: {$not: {$size: 0}}}}})

    Si usted sabe que va a ser sólo la adición de usuarios inexistentes y la eliminación de los usuarios existentes de la user documento, puede simplificar users a un contador en lugar de una matriz, pero la de arriba es más resistente.

  4. 0

    Vistazo a los $tamaño de operador para la comprobación de la matriz de tamaños.

    • No estoy comprobando el tamaño de las matrices. Me fui de un conjunto de llaves antes, puede ser más claro ahora. Un operador equivalente para los documentos y objetos que funcionaría, pero que no parece existir.

Dejar respuesta

Please enter your comment!
Please enter your name here