C# MongoDB filter a value from the Dictionary like object

Hello there, need some help on building Mongodb filter. I have a below data structure
{
"_id" : ObjectId("60054d3e20b5c978eb93bb7f"),
"Image":
{
"en-us" : {"Id":o1n2rpon12prn" , "IsPublished": "false" },
"en-ca" : {"Id":o1n2rpon12prn" , "IsPublished": "true" },
"fr-ca" : {"Id":o1n2rpon12prn" , "IsPublished": "false" }
}
} I would like to build a filter query which will bring all the data where IsPublished= true . A data might have one locale ( en-us) or it can have multiple ( en-us, en-ca) . So, key is dynamic( en-us). Anyone has face similar use case in past( filtering data from dictionary with dynamic keys)? appreciate any help/pointers. TIA

Hey @Rajesh_Patel1,

Welcome to the MongoDB Community!

Based on the sample document you shared, it seems that the image data is stored as a single document in MongoDB, and the language key is dynamic in nature. Therefore, to perform further filtration based on the specific requirements you mentioned, I think using application-side code would be beneficial in this scenario.

However, I have tested the pipeline below, which may give you the required results within ImageV2, but with the language being in the “k” field. Here, I used $objectToArray and then $arrayToObject to transform it back to the original sample document structure.

Here are the sample documents from my test environment:

myTestDb> db.test.find()
[
  {
    _id: ObjectId("64b4e7bd0b74e330f809d554"),
    Image: {
      'en-us': { Id: 'o1n2rpon12prn', IsPublished: 'false' },
      'en-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' },
      'fr-ca': { Id: 'o1n2rpon12prn', IsPublished: 'false' }
    }
  },
  {
    _id: ObjectId("64b4e7bd0b74e330f809d555"),
    Image: {
      'en-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' },
      'fr-ca': { Id: 'o1n2rpon12prn', IsPublished: 'false' }
    }
  },
  {
    _id: ObjectId("64b4e7bd0b74e330f809d556"),
    Image: { 'en-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' } }
  },
  {
    _id: ObjectId("64b4e7bd0b74e330f809d557"),
    Image: { 'en-us': { Id: 'o1n2rpon12prn', IsPublished: 'true' } }
  },
  {
    _id: ObjectId("64b4e7bd0b74e330f809d558"),
    Image: {
      'en-us': { Id: 'o1n2rpon12prn', IsPublished: 'true' },
      'fr-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' }
    }
  }
]

The pipeline is as follows:

db.test.aggregate([
  {
    $addFields: {
      filteredArray: {
        $filter: {
          input: {
            $objectToArray: "$Image",
          },
          cond: {
            $eq: ["$$this.v.IsPublished", "true"],
          },
        },
      },
    },
  },
  {
    $addFields: {
      Imagev2: {
        $arrayToObject: {
          $map: {
            input: "$filteredArray",
            in: {
              k: "$$this.k",
              v: "$$this.v",
            },
          },
        },
      },
    },
  },
  {
    $project: {
      _id: 0,
      Image: 0,
      filteredArray: 0,
    },
  },
])

It will give the following output when using the aforementioned pipeline:

[
  {
    Imagev2: { 'en-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' } }
  },
  {
    Imagev2: { 'en-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' } }
  },
  {
    Imagev2: { 'en-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' } }
  },
  {
    Imagev2: { 'en-us': { Id: 'o1n2rpon12prn', IsPublished: 'true' } }
  },
  {
    Imagev2: {
      'en-us': { Id: 'o1n2rpon12prn', IsPublished: 'true' },
      'fr-ca': { Id: 'o1n2rpon12prn', IsPublished: 'true' }
    }
  }
]

I’ve only briefly tested this out, so I recommend either performing the same in the test environment to see if it suits your use case and requirements or doing it application-side as suggested earlier in my response.

Hope the above helps!

Best,
Kushagra

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.