如何与数组中匹配的值聚合然后排序

Posted

技术标签:

【中文标题】如何与数组中匹配的值聚合然后排序【英文标题】:How to aggregate with value matched in an array then sort 【发布时间】:2020-12-09 23:17:56 【问题描述】:

我有这些收藏:

lists
_id: 1, item: "a", owner: 1
users
_id: 1, subs: [_id: 1, active: "Y",_id: 2, active: "N"]
subs
_id: 1, text: "A"
_id: 2, text: "B"

我想要一个包含用户信息和激活的子信息的列表结果。

_id: 1, item: "a", owner: _id: 1, subs: [_id: _id: 1, text: "A", active: "Y"]

我还想根据“文本”字段对其进行排序。

我尝试过聚合但失败了,

db.getCollection("lists").aggregate(
[
     
        "$lookup" :  
            "from" : "users", 
            "localField" : "owner", 
            "foreignField" : "_id", 
            "as" : "owner"
        
    , 
     
        "$match" :  
            "owner.0.subs" :  
                "$elemMatch" :  
                    "active" : "Y"
                
            
        
    
], 
 
    "allowDiskUse" : false

);

我也在使用 Mongoose,但使用填充失败。 有什么方法可以得到我的结果?

在这里,我更新了我的聚合管道,

[
  
    $lookup: 
      from: "users",
      as: "owner",
      let:  owner: "$owner" ,
      pipeline: [
         $match:  $expr:  $eq: ["$$owner", "$_id"]   ,
         $unwind:  path:"$sub", preserveNullAndEmptyArrays: false ,
         $match:  "subs.active": "Y"  ,
        
          $lookup: 
            from: "plans",
            localField: "subs._id",
            foreignField: "_id",
            as: "subs.plans"
          
        ,
         $unwind:  path:"$subs.plans", preserveNullAndEmptyArrays: false ,
      ]
    
  ,
   $unwind:  path: "$owner", preserveNullAndEmptyArrays: true ,
   '$sort':  item: 1  ,
   '$skip': 0 ,
   '$limit': 20  ]

【问题讨论】:

您有 3 个集合,只有 1 个查找列表->用户。您至少需要另一个查找来将 subs 添加到方程中 【参考方案1】:

您可以将查找与管道和嵌套查找一起使用,

内部查找管道是:

$match您在用户集合中的所有者 ID $unwind 解构 subs 数组,因为我们需要使用 subs 集合查找 $match subs 是否处于活动状态 $lookup 带有 subs 集合 $unwind deconstruct subs._id 我们从 subs 集合中加入 $group重构subs数组 $unwind解构owner数组 $sort item 和分页 $skip$limit
db.getCollection("lists").aggregate([
  
    $lookup: 
      from: "users",
      as: "owner",
      let:  owner: "$owner" ,
      pipeline: [
         $match:  $expr:  $eq: ["$$owner", "$_id"]   ,
         $unwind: "$subs" ,
         $match:  "subs.active": "Y"  ,
        
          $lookup: 
            from: "subs",
            localField: "subs._id",
            foreignField: "_id",
            as: "subs._id"
          
        ,
         $unwind: "$subs._id" ,
        
          $group: 
            _id: "$_id",
            subs: 
              $push: 
                _id: "$subs._id._id",
                text: "$subs._id.text",
                active: "$subs.active"
              
            
          
        
      ]
    
  ,
   $unwind: "$owner" ,
   $sort:  item: 1  ,
   $skip: 0 ,
   $limit: 20 
],  allowDiskUse: false )

Playground


您的第二次编辑:在第一个 $unwind 中的第一次查找中有错误的键名 sub,请更正此问题,

$unwind: path:"$sub", preserveNullAndEmptyArrays: false

$unwind: path:"$subs", preserveNullAndEmptyArrays: false

Your Working Query

【讨论】:

嗨。请检查我的新更新,我可以得到我的结果,但是在排序时,它不起作用。 你到底想要什么,你想按项目名称和分页排序对吗?所以你的查询是无效的检查更新的答案。 你有没有办法删除细节,只计算那些文档而没有跳过和限制? 你的意思是你需要数组的总大小?,使用$size或$count 你能举出使用$count / $size的例子吗?我想计算没有跳过和限制选项的聚合返回的总行数

以上是关于如何与数组中匹配的值聚合然后排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mongodb 聚合中展开嵌套对象数组?

如何查看数据库中的结果是不是与我在数组中的值匹配

如何使用 mongo 聚合循环遍历数组并返回所需的文档?

如何查询并确保返回的值只添加到数组中一次?

如何将数据值与数组值匹配

如何将字段的值聚合到数组中?