1

The following is a notional structure of my contrived "Famous Recipes" database.

This structure is simular to the MongoDB examples from the $redact aggregration chapter.

The biggest difference is that I want to have named access to sections and subsections, as well as additional information stored in objects within a "tags" array, instead of simple strings per the MongodB Examples.

The issue is that I am unable to craft a $redact conditional so it can inspect the tags.name property correctly. I have been unsuccessful in using $elemMatch inside the conditional, and dot notation raises an error as well.

Any suggestions?

{
   _id: 1,
   title: "Secret Recipes of Fast Food Chains",
   tags: [
     { name: "Colonel Sanders", access: ["read"] },
     { name: "Ronald  McDonald", access: ["read"] }
   ],
   year: 2014,
   subsections: [
       {
       subtitle: "Colonel Sander's Famous Recipe",
       tags: [
         { name: "Colonel Sanders", access: ["update", "delete"] },
         { name: "Ronald McDonald"}
       ],
       ingredients: ["salt", "pepper", "paprika", "garlic powder"]
       ]
   {
       subtitle: "Ronald McDonald's McNugget Sauce",
       tags: [
         { name: "Colonel Sanders" },
         { name: "Ronald McDonald", access: ["update", "delete"]  } 
       ],
       ingredients: ["mustard", "ketchup", "salt", "vinegar"]
   }
}

My non-working query would read something like this:

var access = "Colonel Sanders"
db.recipes.aggregate(
  [
    { $match: { "year": 2014 } },
    { $redact:
    {
        $cond: {
                 if: { $eq: [ tags: { $elemMatch : { "name" } }, access ] },
                 then: "$$DESCEND",
                 else: "$$PRUNE"
               }
      }
    }
  ]
)
JohnK
  • 153
  • 7

1 Answers1

0

Old question, but I was suffering with the same problem.

First, your example fixed:

db.recipes.insert({
  _id: 1,
  title: "Secret Recipes of Fast Food Chains",
  tags: [{
    name: "Colonel Sanders",
    access: ["read"]
  }, {
    name: "Ronald  McDonald",
    access: ["read"]
  }],
  year: 2014,
  subsections: [{
    subtitle: "Colonel Sander's Famous Recipe",
    tags: [{
      name: "Colonel Sanders",
      access: ["update", "delete"]
    }, {
      name: "Ronald McDonald"
    }],
    ingredients: ["salt", "pepper", "paprika", "garlic powder"]
  }, {
    subtitle: "Ronald McDonald's McNugget Sauce",
    tags: [{
      name: "Colonel Sanders"
    }, {
      name: "Ronald McDonald",
      access: ["update", "delete"]
    }],
    ingredients: ["mustard", "ketchup", "salt", "vinegar"]
  }]
})

After that I wrote the following query:

var access = "Colonel Sanders"
db.recipes.aggregate(
  [{
    $match: {
      "year": 2014
    }
  }, {
    $redact: {
      $cond: {
        if : {
          $or: [{$eq: ["$name", access]}, {$not: "$name"}]
        },
        then: "$$DESCEND",
        else :"$$PRUNE"
      }
    }
  }]
)

Give a try. You can found more information on this other question: 3985214

laubstein
  • 1
  • 1