How should I put $cond into $match?

Currently doing an exercise from chapter1. I’m trying to count, how many movie titles from movies collection, only has one word.
Tried to do comparison with one value in the field name like

    {"$size": {"$split": ["title", " "]}}: {"$eq": 1}

didn’t think this way would work, so I tried to use $cond

db.movies.aggregate([{"$project": {"xx": {"$cond": {"if": {"$eq": [{"$size": {"$split": ["$title", " "]}}, 1]}, 
    												"then": "$title",
                     										 "else": null}
                     }, {
                     "$group": {"_id": {"$not": null}, "count": {"$sum": 1}}

Tried to switch to $project instead of $match coz Im getting unknown top level operator: $cond error without the “xx”(getting error when used in $match, without “xx” field), which I have no idea what should I put in there

Now I’m getting the result, but since Im using it in $project it displays all docs including incorrect ones.
Also by adding the $not in $group stage, I thought I could get rid of the nulls result, but turns out it has no effect.

And then I tried $expr

						{"$eq": [{"$split": ["$title", " "]}, 1]	}

I wonder how should I put $cond statement into $match, and is it actually possible to remove null results? Why its not working for the $expr part?


Wait, I found the way to get the right results. Just change $group stage to a $match stage

"$match": {"xx": {"$ne": "NA"}}

But I still want to know the things I asked above

Hi @vid_Proli,
If your objective is to find:

Then you don’t need to add a $project stage.

The most efficient and straightforward approach for this would be to use a $match stage and then count the number of documents in the next stage.

Also, the following is not a valid syntax:

The correct syntax to compare the number of words in a string would be:

{$match: {$expr: {$eq: [{$size: {$split: ["$title", " "]}}, 1]}}}

(Which you have already used in your $project stage)

You can use the $expr operator if you want to use $cond, but usually, you might not want to do that inside a $match stage, in cases like that I’d recommend using a $project stage.

You should remove such results as early as possible, I’d recommend using a $match stage and filter out all the movies having the title as null, and it will be much more efficient for the pipeline to process in the subsequent stages.

That’s just the way pipelines are built, it completely depends on the complexity of the logic that you want to implement. I’d recommend using variables to break complex/nested objects into small chunks.

For e.g.:
The following stage:

db.collection.aggregate([{$match: {$expr: {$eq: [{$size: {$split: ["$title", " "]}}, 1]}}}])

can be broken into:

let countWordsInTItle = {$size: {$split: ["$title", " "]}}
let matchStage = {$match: {$expr: {$eq: [countWordsInTitle, 1]}}}

I hope it helps.

In case you have any doubts, please feel free to reach out to us.

Thanks and Regards.
Sourabh Bagrecha,
Curriculum Services Engineer

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