Cyran
Cyran

Reputation: 15

$addFields in mongoDB aggregation pipeline

I'm using the cloud mongoDB atlas online version of the aggregation pipeline builder. My document looks like this:

_id: 'a314314133351sd4d'
type: 'Test_993das'

What I want to achieve is that I get an custom field with name customField that counts all the documents that have a substring Test in type:

customField: 6

However when I use stage $addFields nothing works with strings. Even stuff from the docs. It seems that $regexMatch is not recognized in addFields stage even though the docs suggest this should be possible.

{ $addFields: { customField: { $regexMatch: { input: "$type", regex: "Test_*" } }

Upvotes: 1

Views: 2591

Answers (2)

Rezy Ega
Rezy Ega

Reputation: 1

{
  $addFields: {
    hasNewMessage: {
      $cond: { if: {$gt: [{ $size: "$messages" }, 0]}, then: true, else: false}
    }
  }
}

Upvotes: 0

MikkolidisMedius
MikkolidisMedius

Reputation: 4844

As noted by tom slabbaert, $regexMatch is available only on MongoDB 4.2.x, also, your regex is not valid (should either be Test_ or Test_.*).

However, the syntax you are using will only produce customField: true (or false), not a count. Counts are aggregate functions and therefore need to operate on a group of documents. An aggregation pipeline operates on each single document unless you use a grouping stage like $group, $bucket or $count.

What this means is that, in your example, $addField will evaluate the regex and add the field on each document. So probably you want something like:

[
  { $match: { 'type': { $regex: /Test_.*/ } } },
  { $count: 'customField' }
]

Also, if your regex should match only the start of the string, you will get better performance if you anchor the regex, like this: /^Test_.*/

Upvotes: 1

Related Questions