Home > Net >  How do I find multiple mongo documents using queries but always start with the first query?
How do I find multiple mongo documents using queries but always start with the first query?

Time:11-07

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' },{} ],
}

CodePudding user response:

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' },
...
]```

CodePudding user response:

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

CodePudding user response:

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

  • Related