Estoy trabajando en MongoDB y el próximo proyecto js. Quiero aplicar filtro en productos. Hay varios filtros. Quiero incluir un filtro y un operador solo si el valor de una variable no está vacío o indefinido Quiero algo como esto que funcione
Product.find({ $and:[ { tag : { $in : preferences,}, {$cond:{ if: { $ne: ['$allergens'], []],}, then: { allergens: {$in :allergens }, if:{ $ne: ['$type'],''],}, then: { type: type , } } }) }]¿Cuál sería la forma correcta de hacer esto? Gracias
Compruebe la sintaxis correcta:
{ $and: [ { Expression1 }, { Expression2 }, ..., { ExpressionN } ] } or { { Expression1 }, { Expression2 }, ..., { ExpressionN }}Esto debería funcionar. El truco es usar $cond más $ifNull para ver si el campo no está configurado.
var r = [ { tag: [ "A","B"], allergens: ["pollen","badJokes"], type: "foo" }, { tag: [ "B","C"], type: "foo" }, { tag: [ "C","D"], allergens: ["other"] }, { tag: [ "E","D"], allergens: ["corn"] } ]; db.foo.drop(); db.foo.insert(r); var tags = [ "C","A" ]; var type = 'foo'; var allergens = ['pollen','corn']; c = db.foo.aggregate([ {$match: {$expr: {$and: [ {$ne:[ [], {$setIntersection: [ "$tag", tags ]} ] }, {$cond: { if: {$eq:["$type", {$ifNull:["$type",null]} ]}, then: {$eq:["$type",type]}, else: true }}, {$cond: { if: {$eq:["$allergens", {$ifNull:["$allergens",null]} ]}, then: {$gt:[{$size: {$setIntersection: [ "$allergens", allergens ]}} , 0 ]}, else: true }} ]} }} ]); Alternativamente, podría ser más fácil construir la expresión $and programáticamente fuera de la consulta:
// Init the and expression array with tags since we always want that: var andExpr = [ {$ne:[ [], {$setIntersection: [ "$tag", tags ]} ] } ]; if(type != undefined) { andExpr.push({$eq:["$type",type]}); } if(allergens != undefined) { // Use $ifNull to defend against missing field since // $size on a null field will fail, not yield 0: andExpr.push({$gt:[{$size: {$setIntersection: [ {$ifNull:["$allergens",[]]}, allergens ]}} , 0 ]}); } c = db.foo.aggregate([ {$match: {$expr: {$and: andExpr}} } ]);