2

I have the following document structure on my mongodb collection:

{
"_id" : "5Ci9sLeBu2iPbWtR5",
"productId" : "010101111",
"description" : "PRODUCT EXAMPLE REF 1001",
"prices" : [ 
    {
        "priceId" : 10,
        "description" : "Promotions",
        "price" : 97.99
    },
    {
        "priceId" : 15,
        "description" : "Retail list",
        "price" : 105.65
    },
    {
        "priceId" : 20,
        "description" : "Standard list",
        "price" : 109.10
    }
]}

What I want is query only specific array of priceIds, for example: [10,20], resulting:

{
"_id" : "5Ci9sLeBu2iPbWtR5",
"productId" : "010101111",
"description" : "PRODUCT EXAMPLE REF 1001",
"prices" : [ 
    {
        "priceId" : 10,
        "description" : "Promotions",
        "price" : 97.99
    },
    {
        "priceId" : 20,
        "description" : "Standard list",
        "price" : 109.10
    }
]}

Using $in operator with $filter like this (the perfect imaginary scenario):

db.getCollection('products').aggregate([
{$match: { "productId":"010101111" }},
{$project: { 
    "prices": {
        $filter: {
            input: "$prices",
            as: "price",
            cond: { $in: ["$$price.priceId",[10, 20]] }
        }
    }
}}])

it doesn't work, because mongodb complains about $in operator ("invalid operator '$in'").

Of course, I can do that with $unwind, but I'll have a performance problem, because I need to group again after all.

The closest answers I've found for my question were these two:

  1. Retrieve only the queried element in an object array in MongoDB collection
  2. Filter array using the $in operator in the $project stage

but none of them were about searching with array filter in subdocuments.

1 Answers1

1

The $in operator is only valid within the aggregation pipeline for MongoDB 3.4+. However, a workaround involves using the set operators. Use $setIsSubset as substitute which returns true if all elements of the first set appear in the second set, including when the first set equals the second set:

cond: { $setIsSubset: [["$$price.priceId"],[10, 20]] }
chridam
  • 100,957
  • 23
  • 236
  • 235
  • 1
    Thank you so much! The workaround worked in my current version (3.2). I figured out that I need to upgrade to 3.4 indeed. – Bruno Neumann Mar 03 '18 at 20:05