0

I'm trying to create a viewAmount attribute on a Video document where we sum up something it owns called Views, but only where view.valid = true.

This is what I have so far:

{
        $project: {
          title: 1,
          viewAmount: { $size: "$views" }
        }
      },

What can I add to do a conditional check if the view is valid or not rather than just noting the size? Do I have to use the $unwind operator? Thanks

Edit:

I am actually checking if view.validity (checkedView.validity) is equal to 'real'.

Here's my updated answer so far which isn't quite working:

{ $project: {
          title: 1,
          viewAmount: {
            $size: {
              $filter: {
                input: "$checkedViews",
                as: "view",
                cond: { $eq: ["$$view.validity", "real"] }
              }
            }
          }
        }
      },

An example Video:

{
    "_id" : ObjectId("59b5d09980348a3ec3541acc"),
    "checkedViews" : [ 
        ObjectId("59b5d0b280348a3ec3541acd"), 
        ObjectId("59b5d0bf80348a3ec3541ace"), 
        ObjectId("59b5d1dbd8f37d4ab797fa5c")
    ]
}

An example checkedView:

{
    "_id" : ObjectId("59b5d0b280348a3ec3541acd"),
    "updatedAt" : ISODate("2017-09-10T23:54:26.752Z"),
    "createdAt" : ISODate("2017-09-10T23:54:26.752Z"),
    "video" : ObjectId("59b5d09980348a3ec3541acc"),
    "validity" : "real",
    "__v" : 0
}
Anthony
  • 13,434
  • 14
  • 60
  • 80
  • 1
    Try `{ "$project": { "$size": { "$filter": { "input": "$views", "as": "view", "cond": "$$view.valid" } } } }` – s7vr Sep 26 '17 at 19:19
  • added an edit @Veeram – Anthony Sep 26 '17 at 19:36
  • 1
    Consider adding test data. It's hard to tell without the data and without knowing problem you see when you run the query. – s7vr Sep 26 '17 at 19:38
  • Okay updated. It looks like the conditional is working, if my conditional is: `cond: { $eq: [1, 1] }`, I get the proper viewAmount, but if I do `cond: { $eq: ['$$view.validity', 'real'] }`, then I get 0 as the viewAmount @Veeram – Anthony Sep 26 '17 at 19:52
  • ah I see. You have two separate collections. You need a lookup stage before filter. Something like `{ $lookup: { from: "checkedView", localField: "checkedViews", foreignField: "_id", as: "checkedViews" } }` – s7vr Sep 26 '17 at 19:55
  • Cool, I think that will work (haven't tested but seems legit with what I've read about $lookup), can you add that as an answer? – Anthony Sep 26 '17 at 19:57
  • Possible duplicate of [Get looked up array count for a document](https://stackoverflow.com/questions/43821447/get-looked-up-array-count-for-a-document) – s7vr Sep 26 '17 at 20:07
  • Can't get this one to work @Veeram: `{ $lookup: { from: "views", localField: "checkedViews", foreignField: "_id", as: "populatedViews" } },` (The collection is in the db as only 'views' not 'checkedViews') – Anthony Sep 26 '17 at 20:19
  • This is working now: ` { $lookup: { from: "views", localField: "checkedViews.id", foreignField: "id", as: "checkedViews" } },`, but it's loading checkedViews from other uploads onto each uploads (ie they're not grouped by an _id). I thought $lookup would automatically group by ID but maybe I have to do it myself? – Anthony Sep 26 '17 at 20:34
  • May be your not matching them correctly. Check your foreignField variable. – s7vr Sep 26 '17 at 21:09
  • I'm correctly matching them, but I'm getting all views documents from the database (898) and they're being attached to every video. I just want to attach them when the Id matches. I want to do a filter but I can't find a way to do something like `cond: { $eq: ['$$view.id', '$checkedViews.id'] }` <--- is there a syntax for this so I can filter and match by ID? – Anthony Sep 26 '17 at 21:12

0 Answers0