Estoy tratando de consulta de la propiedad, que es una matriz de referencia a otro esquema y algunos datos adicionales. Para una mejor aclaración, he aquí el esquema:

    var orderSchema = new Schema({
        orderDate: Date,
        articles: [{
            article: {
                type: Schema.Types.ObjectId,
                ref: 'Article'
            },
            quantity: 'Number'
        }]
    }),
    Order = mongoose.model('Order', orderSchema);

Mientras que he logrado con éxito la consulta de la referencia, es decir:

Order.find({}).populate('articles.article', null, {
    price: {
        $lte: 500
    }
}).exec(function(err, data) {
    for (var order of data) {
        for (var article of order.articles) {
            console.log(article);
        }
    }
});

Tengo algunos problemas consultar el quantity atributo, es decir, esto no funciona:

Order.find({}).where({
    'articles.quantity': {
        $gte: 5
    }
}).populate('articles.article', null, {
    /*price: {
        $lte: 500
    }*/
}).exec(function(err, data) {
    for (var order of data) {
        for (var article of order.articles) {
            console.log(article);
        }
    }
});

Es la base de la consulta en quantity? Y si es así, ¿cuál sería el mejor enfoque?

Gracias!

ACTUALIZACIÓN:

El problema es que el resultado es un conjunto completo, o nada (ver actualizado pregunta). Quiero obtener sólo aquellos registros que tienen la cantidad más o igual que 5. Con su (y la mía) enfoque puedo conseguir cualquiera de los registros no en todos (si me puse $gte: 5001) o ambos registros (si me puse $gte:5000)

{
    "_id": ObjectId('56fe76c12f7174ac5018054f'),
    "orderDate": ISODate('2016-04-01T13:25:21.055Z'),
    "articles": [
        {
            "article": ObjectId('56fe76c12f7174ac5018054b'),
            "quantity": 5000,
            "_id": ObjectId('56fe76c12f7174ac50180551')
        },
        {
            "article": ObjectId('56fe76c12f7174ac5018054c'),
            "quantity": 1,
            "_id": ObjectId('56fe76c12f7174ac50180552')
        }
    ],
    "__v": 1
}
Puede usted explicar por qué la consulta articles.quantity no funciona? ¿Hay alguna salida que se puede agregar a la pregunta?
He quitado la mala respuesta. Se puede comprobar que la parte de la consulta devuelve los resultados deseados, sin rellenar? Si se devuelve la totalidad de la matriz, a continuación, hay un problema en la consulta, como rellenar las obras en el resultado de la consulta.
Es su problema el mismo que en here ?
Es «algo» es, excepto el concepto aquí es que algunos de los datos reside en otra colección y hay un deseo de .populate() y «filtro» en los resultados. Casi me ponen una bodega ( de hecho yo lo hice, pero retirado ), ya no en el hecho de tener elementos de «dos» de larga data respuestas, pero en realidad es la «única» manera. Así que en mi humilde opinión es una especie de se encuentra en su propio.

OriginalEl autor uglycode | 2016-04-02

1 Comentario

  1. 3

    Que necesita un «proyecto», el partido aquí, ya que todos los MongoDB consulta no es buscar un «documento» que ha «al menos un elemento» que es «mayor que» la condición de que usted solicitó.

    Para el filtrado de una «matriz» no es lo mismo que la «consulta» de enfermedad que padece.

    Un simple «proyección» se acaba de devolver el «primer» elemento coincidente para que condtion. Así que probablemente no sea lo que quieres, pero como un ejemplo:

    Order.find({ "articles.quantity": { "$gte": 5 } })
        .select({ "articles.$": 1 })
        .populate({
            "path": "articles.article",
            "match": { "price": { "$lte": 500 } }
        }).exec(function(err,orders) {
           //populated and filtered twice
        }
    )

    Que «algo» hace lo que quiere, pero el problema es que realmente va a ser que sólo va a volver jamás a la mayoría de los uno elemento dentro de la "articles" matriz.

    Para hacer esto correctamente, deberá .aggregate() para filtrar el contenido de la matriz. Idealmente, esto se hace con MongoDB 3.2 y $filter. Pero también hay un modo especial a .populate() aquí:

    Order.aggregate(
        [
            { "$match": { "artciles.quantity": { "$gte": 5 } } },
            { "$project": {
                "orderdate": 1,
                "articles": {
                    "$filter": {
                        "input": "$articles",
                        "as": "article",
                        "cond": {
                           "$gte": [ "$$article.quantity", 5 ]
                        }
                    }
                },
                "__v": 1
            }}
        ],
        function(err,orders) {
            Order.populate(
                orders.map(function(order) { return new Order(order) }),
                {
                    "path": "articles.article",
                    "match": { "price": { "$lte": 500 } }
                },
                function(err,orders) {
                    //now it's all populated and mongoose documents
                }
            )
        }
    )

    Entonces, ¿qué pasa aquí es que el «filtrado» de la matriz que sucede dentro de la .aggregate() declaración, pero, por supuesto, el resultado de esto ya no es un «mangosta documento» porque uno de los aspectos de .aggregate() es que puede «alterar» la estructura del documento, y por esta razón mangosta «presume» que es el caso y sólo devuelve un «simple objeto».

    Que no es realmente un problema, ya que cuando vea la $project etapa, en realidad estamos pidiendo a todos de la misma campos presentes en el documento de acuerdo con el esquema definido. Así que aunque se trata de un «simple objeto» no hay ningún problema «casting» de nuevo en una mangosta documento.

    Aquí es donde la .map() viene, ya que devuelve un array de convertir a «documentos», que luego es importante para la siguiente etapa.

    Ahora llamada Modelo.rellenar() que puede, a continuación, ejecute el más «población» en la «matriz de la mangosta documentos».

    El resultado es finalmente lo que usted desea.


    MongoDB versiones anteriores de 3.2.x

    Las únicas cosas que realmente cambia aquí son la agregación de canalización, de Modo que es todo lo que necesita ser incluido por razones de brevedad.

    MongoDB 2.6 – Puede filtrar las matrices con una combinación de $map y $setDifference. El resultado es un «conjunto», pero que no es un problema cuando la mangosta crea una _id campo en todos los sub-documento de matrices por defecto:

        [
            { "$match": { "artciles.quantity": { "$gte": 5 } } },
            { "$project": {
                "orderdate": 1,
                "articles": {
                    "$setDiffernce": [
                       { "$map": {
                          "input": "$articles",
                          "as": "article",
                          "in": {
                             "$cond": [
                                 { "$gte": [ "$$article.price", 5 ] },
                                 "$$article",
                                 false
                             ]
                          }
                       }},
                       [false]
                    ]
                },
                "__v": 1
            }}
        ],

    Las revisiones anteriores de que debe usar $relajarse:

        [
            { "$match": { "artciles.quantity": { "$gte": 5 } }},
            { "$unwind": "$articles" },
            { "$match": { "artciles.quantity": { "$gte": 5 } }},
            { "$group": {
              "_id": "$_id",
              "orderdate": { "$first": "$orderdate" },
              "articles": { "$push": "$articles" },
              "__v": { "$first": "$__v" }
            }}
        ],

    El $de búsqueda Alternativos

    Otra alternativa es que se acaba de hacer de todo en el «servidor» en su lugar. Esta es una opción con $de búsqueda de MongoDB 3.2 y superior:

    Y a pesar de que ésas son simplemente documentos, solo los mismos resultados que con lo que tengo de la .populate() enfoque. Y, por supuesto, siempre se puede ir y «echar» a la mangosta documentos en todos los casos, de nuevo, si usted realmente debe.

    El «menor» Ruta de acceso de

    Esto realmente va de nuevo a la original declaración en la que, básicamente, sólo «aceptar» que la «consulta» no está destinado a «filtrar» el contenido de la matriz. El .populate() puede happilly hacerlo becuse es otra de las «consultas» y es de relleno en «documentos» por conveniencia.

    Así que si usted realmente no está ahorrando «bucketloads» de ancho de banda por la eliminación de los adicionales de los miembros de la matriz en el original del documento matriz, a continuación, sólo .filter() en el procesamiento posterior código:

    El código donde la solución utiliza "$filter" tiene algunos errores, a saber: Error: Arguments must be aggregate pipeline operators
    Eso significa que usted no tiene MongoDB 3.2 o superior. El resto del contenido es para usted.
    Gracias. Aún así, creo que hay algunos problemas con } símbolos, no se cierra correctamente o demasiados… me sale el error: «91,17: Espera ‘}’ para que coincida con ‘{‘ de la línea 85 y en su lugar vio a ‘{‘.` Creo que esto es en todas las posibles soluciones.
    Bastante simple, errores de sintaxis. Corregidos. Lo siento, no fue completamente sintácticamente correcta por falta de un corchete de cierre o dos a la hora de explicar un concepto avanzado. Y se escribe directamente en la cuestión que aquí en lugar de una IDE. Algunos podrían decir «gracias» por tomarse el tiempo para explicar los conceptos.
    Yo no quiero salir como ingrato, yo estaba simplemente diciendo que eran errores de sintaxis en el código, si alguien puede encontrar este hilo y copiar/pegar su solución. Por supuesto, estoy muy agradecido por su tiempo y esfuerzo. Voy a aceptar su respuesta.

    OriginalEl autor Blakes Seven

Dejar respuesta

Please enter your comment!
Please enter your name here