skip to Main Content

I’m trying to return all documents which satisfy document.field.value > document.array.length. I’m trying to do this using MongoClient in ExpressJS and was not able to find answers on SO.

Here is what I have tried but this gives an empty list.

const db = ref()
const c = db.collection(t)
const docs = await c.find({ 
                "stop.time":{$gt: new Date().toISOString()},
                "stop.expect": {$gt: { $size: "stop.riders"}}
            })
console.log(docs)

Also tried replacing

"stop.expect": {$gt: { $size: "stop.riders"}}

with the below code which does not compile

$expr: {$lt: [{$size: "stop.riders"}, "stop.expect"]}

Sample data:

{ "stop": { "expect":3, "riders": ["asd", "erw", "wer"] } },
{ "stop": { "expect":4, "riders": ["asq", "frw", "wbr"] } }

2

Answers


  1. To filter the query with a complex query involving the calculation, you need to use the $expr operator, which allows the aggregation operators.

    Next, within the $expr operator, to refer to the field, you need to add the prefix $.

    db.collection.find({
      $expr: {
        $lt: [
          {
            $size: "$stop.riders"
          },
          "$stop.expect"
        ]
      }
    })
    

    Demo @ Mongo Playground

    Login or Signup to reply.
  2. To compare fields within a document to each other, you must use $expr. It would look like this:

    const docs = await c.find({ 
      $expr: { $gt: ["$stop.expect", { $size: "$stop.riders" }] },
    });
    

    I omitted the stop.time condition because it’s not in your sample data and it’s unclear what type of field it is, if it actually is in your data (whether it’s a Date or String would be very important).

    Note that this sort of query is unable to use an index.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search