skip to Main Content

I need the first part of $or (or equivalent query) to be resolved first and to make sure that the first query is always part of the result.

Must use query, not aggregation.

[
    { "docId": "x1" },
    { "docId": "x2" },
    { "docId": "x3" },
    { "docId": "x4" },
    { "docId": "x5" },
    ...
    { "docId": "xn" },
]

Query:

{
  '$or': [ { docId: 'x434' },{} ],
}

I need x434 to be part of the query result, regardless of all other results.

Expected result:

[
{ docId: 'x434' },
{ docId: 'x12' },
{ docId: 'x1' },
...
]

Return:

[
{ docId: 'xn' },
{ docId: 'xn' },
{ docId: 'xn' },
...
]

Results by x434 is not always returned

I tried $or and $and queries but nothing worked. I tried regex too

{
  '$or': [ { docId: 'x434' },{} ],
}

3

Answers


  1. Chosen as BEST ANSWER

    So the solution can only be an aggregation:

    $match: {
      '$or': [ { docId: 'x434' },{} ],
    },
    $addFields: {
            order: {
            $cond: [
              {
                $in: [
                  "$docId",
                  ['x434']
                ]
              },
              0,
              1
            ]
          }
    },
    $sort: {
      order: 1
    },
    $limit: 20
    

    Result:

    { docId: 'x434' },
    { docId: 'x12' },
    { docId: 'x1' },
    ...
    ]```
    

  2. A straightforward solution can use $facet:

    db.collection.aggregate([
      {$facet: {
          allOther: [{$match: {docId: {$ne: "x434"}}}, {$limit: 19}],
          wanted: [{$match: {docId: "x434"}}]
      }},
      {$project: {data: {$concatArrays: ["$wanted", "$allOther"]}}},
      {$unwind: "$data"},
      {$replaceRoot: {newRoot: "$data"}}
    ])
    

    See how it works on the playground example

    Login or Signup to reply.
  3. You can use $unionWith. It’s behaviour is similar to UNION ALL in SQL so you can persist x434 at the start. Remember to exclude x434 in the $unionWith pipeline to avoid duplicate if needed

    db.collection.aggregate([
      {
        $match: {
          "docId": "x434"
        }
      },
      {
        "$unionWith": {
          "coll": "collection",
          "pipeline": [
            // exclude x434 to avoid duplicate
            {
              $match: {
                "docId": {
                  $ne: "x434"
                }
              }
            }// put your other queries here
            
          ]
        }
      }
    ])
    

    Mongo Playground

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