mongodb 如何使用查询查找多个mongo文档,但总是从第一个查询开始?

lpwwtiir  于 2022-11-22  发布在  Go
关注(0)|答案(3)|浏览(185)

我需要首先解析$or(或等效查询)的第一部分,并确保第一个查询始终是结果的一部分。
必须使用查询,而不是聚合。

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

查询:

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

我需要将x434作为查询结果的一部分,而不考虑所有其他结果。
预期结果:

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

退货:

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

不一定会传回x434的结果
我尝试了$or$and查询,但没有任何效果。我也尝试了regex

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

wgx48brx1#

因此解决方案只能是一个聚合:

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

结果:

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

vngu2lb82#

一个简单的解决方案可以使用$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"}}
])

了解它在playground example上的工作原理

toiithl6

toiithl63#

您可以使用$unionWith。它的行为类似于SQL中的UNION ALL,因此您可以在开始时持久化x434。请记住在$unionWith管道中排除x434,以避免重复(如果需要

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

相关问题