Dynamically filter fields which might even be nested in a document - updated

@turivishal Can you please help me with this ? It is similar to the other problem you helped me with.

Dynamically filter fields which might even be nested in a document

Need to filter “title” and “description” from the documents. This is just at the first level, but i also need to solve it for the nested documents.

{
   "myobject":{
      "type":"object",
      "properties":{
         "ticketing":{
            "type":"object",
            "title":"Ticketing",
            "description":"Ticketing",
            "properties":{
               "sth_history":{
                  "type":"array",
                  "title":"Season Ticket Holder Season History",
                  "description":"Season Ticket Holder Season History",
                  "items":{
                     "type":"object",
                     "properties":{
                        "season":{
                           "title":"Season: Season Ticket Holder",
                           "description":"Purchased any type of package between 10-81 games",
                           "type":"integer",
                           "meta:type":"int"
                        }
                     },
                     "meta:type":"object"
                  },
                  "meta:type":"array"
               },
               "stubhub_seller":{
                  "type":"object",
                  "title":"Ticketing Stubhub Seller",
                  "description":"Ticketing Stubhub Seller",
                  "properties":{
                     "season_sales":{
                        "type":"array",
                        "title":"Ticketing Stubhub Seller Season Sales",
                        "description":"Ticketing Stubhub Seller Season Sales",
                        "items":{
                           "type":"object",
                           "properties":{
                              "season":{
                                 "title":"Season: Stubhub Seller",
                                 "description":"Season: Stubhub Seller",
                                 "type":"integer",
                                 "meta:type":"int"
                              }
                           },
                           "meta:type":"object"
                        },
                        "meta:type":"array"
                     },
                     "games_sold_total":{
                        "title":"Total Stubhub Games Sold",
                        "description":"Total Stubhub Games Sold",
                        "type":"integer",
                        "meta:type":"int"
                     }
                  },
                  "meta:type":"object"
               }
            },
            "meta:type":"object"
         },
         "shop":{
            "type":"object",
            "title":"Shop",
            "description":"Shop",
            "properties":{
               "top_categories_current_season":{
                  "type":"array",
                  "title":"Top Shop Categories Current Season",
                  "description":"Top Shop Categories Current Season",
                  "items":{
                     "type":"object",
                     "properties":{
                        "merch_category":{
                           "title":"Top Shop Product Types Purchased This Season",
                           "description":"Top Shop Product Types Purchased This Season",
                           "type":"string",
                           "meta:type":"string"
                        },
                        "spend":{
                           "title":"Top Shop Product Types Spend Purchased This Season",
                           "description":"Top Shop Product Types Spend Purchased This Season",
                           "type":"number",
                           "meta:type":"number"
                        }
                     },
                     "meta:type":"object"
                  },
                  "meta:type":"array"
               },
               "top_categories_total":{
                  "type":"array",
                  "title":"Shop Top Categories Total",
                  "description":"Shop Top Categories Total",
                  "items":{
                     "type":"object",
                     "properties":{
                        "merch_category":{
                           "title":"Top 5 Shop Product Types Purchased Ever",
                           "description":"Top 5 Shop Product Types Purchased Ever",
                           "type":"string",
                           "meta:type":"string"
                        },
                        "spend":{
                           "title":"Top 5 Shop Product Types Spend Ever",
                           "description":"Top 5 Shop Product Types Spend Ever",
                           "type":"number",
                           "meta:type":"number"
                        }
                     },
                     "meta:type":"object"
                  },
                  "meta:type":"array"
               }
            },
            "meta:type":"object"
         }
      },
      "meta:type":"object"
   }
}

Hello @waykarp,

If it is a fixed structure then you can use the same approach as answered here

First of all, I would suggest you improve your schema design, because this kind of operation impacts the server and slow execution,

I would suggest you do this kind of operation on the client side/front-end side.

Currently, there is no straight way to do this in an aggregation query.

If this is totally required in aggregation query then you can use javascript code in the $function operator, but make sure you read important notes in the document.

2 Likes

Yeah! I can understand the schema isn’t done the correct way. But, this is what we eventually have, and need to think for a workaround to deal with it.

Using the pattern you shared in the previous post, i tried to build something on top of it. But, not able to get a solution for documents that are of type:“object” and some have nested “properties” but some don’t.

{
        $project: {
            "type: 1,
            "properties": {
                $map: {
                    input: { $objectToArray: "$properties" },
                    in: {
                        k: "$$this.k",
                        v: {
                            $switch: {
                                branches: [
                                    {
                                        case: { $or: [{$and:[{ $eq: ["$$this.v.type", "object"]}]}]},
                                        then: { 
                                                $map: { input: { $objectToArray: "$$this.v.properties" }, 
                                                in:  { k: "$$this.k", v: "$$this.v" }} 
                                        }
                                    },
                                    {
                                        case: { $or: [{$and:[{ $eq: ["$$this.v.type", "array"] }]}]},
                                        then: { 
                                                $map: { input: { $objectToArray: "$$this.v.items.properties" }, 
                                                in:  { k: "$$this.k", v: "$$this.v" }} 
                                        }
                                    }
                                ], default: "$$this.v"
                            }
                        }
                    }
                }
            }
        }
    },

Can you please recommend a way around it? If with “objectToArray”, i have a document with type=“object” and has “properties” do this and the document without “properties” do something else.

"myobject":{
      "type":"object",
      "properties":{
         "ticketing":{
            "type":"object",
            "title":"Ticketing",
            "description":"Ticketing",
            "properties":{
               "sth_history":{
                  "type":"array",
                  "title":"Season Ticket Holder Season History",
                  "description":"Season Ticket Holder Season History",
                  "items":{
                     "type":"object",
                     "properties":{
                        "season":{
                           "title":"Season: Season Ticket Holder",
                           "description":"Purchased any type of package between 10-81 games",
                           "type":"integer",
                           "meta:type":"int"
                        }
                     },
                     "meta:type":"object"
                  },
                  "meta:type":"array"
               }
            }
        },
        "abc" : {
            "title" : "Identifier",
             "type":"object",
            "description" : "Identity of the consumer"
        }
    }
}

@turivishal I was able to get it working but running into challenge to convert it back to Object

{
        $project: {
            "type: 1,
            "properties": {
                $map: {
                    input: { $objectToArray: "$properties" },
                    in: {
                        k: "$$this.k",
                        v: {
                            $switch: {
                                branches: [
                                    {
                                        case: { $or: [{$and:[{ $eq: ["$$this.v.type", "object"]}]}]},
                                        then: { 
                                                 $cond: [
                                                    { $ifNull: ["$$this.v.properties", false] },
                                                    { 
                                                       $map: { 
                                                           input: { $objectToArray: "$$this.v.properties" }, 
                                                            in:  { 
                                                                k: "$$this.k", 
                                                                v: {
                                                                    $cond: [
                                                                        { $ifNull: ["$$this.v.properties", false] },
                                                                        { 
                                                                           $map: { 
                                                                               input: { $objectToArray: "$$this.v.properties" }, 
                                                                                in:  { 
                                                                                    k: "$$this.k", 
                                                                                    v: "$$this.v"
                                                                                }
                                                                            }
                                                                         },
                                                                         "$$this.v"
                                                                     ]
                                                                } 
                                                            }
                                                        }
                                                     },
                                                     "$$this.v"
                                                 ]
                                
                                        }
                                    },
                                    {
                                        case: { $or: [{$and:[{ $eq: ["$$this.v.type", "array"] }]}]},
                                        then: { 
                                                $map: { input: { $objectToArray: "$$this.v.items.properties" }, 
                                                in:  { k: "$$this.k", v: "$$this.v" }} 
                                        }
                                    },
                                    { case: { $gt: [ 0, 5 ] }, then: "greater than" }
                                ], default: "$$this.v"
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            "properties.v.title":0,
            "properties.v.description":0,
            "properties.v.v.title":0,
            "properties.v.v.description":0,
            "properties.v.v.v.title":0,
            "properties.v.v.v.description":0,
        }
    },  

Need help to convert it back to Object.