$group 和 $lookup 没有提供正确的数据

Posted

技术标签:

【中文标题】$group 和 $lookup 没有提供正确的数据【英文标题】:$group and $lookup is not giving proper data 【发布时间】:2021-10-26 08:22:34 【问题描述】:

我有这样的代码

const aggregate = [];
const lookup = 
  $lookup: 
    from: "balances",
    localField: "accountNumber",
    foreignField: "account_id",
    as: "bankbalance",
  ,
;
const unwind = 
  $unwind: "$bankbalance",
;
const match = 
  $match: 
    "bankbalance.date": 
      $gte: startDate,
      $lte: endDate,
    ,
    userId: mongoose.Types.ObjectId(userId),
    isActive: 1,
    type: "accountType"
  ,
;
const group = 
  $group: 
    _id: '$_id',
    accountNumber:"$first":"$accountNumber",
    balances: 
      $addToSet:  date: "$$ROOT.date", amount: "$$ROOT.amount" ,
    ,
  ,
;

aggregate.push(lookup);
aggregate.push(unwind);
aggregate.push(group);
aggregate.push(match);

let data = await BankAccounts.aggregate(aggregate);

这段代码给了我空的 [] 数据,如果我不使用 $group 那么它给我的数据是这样的


_id: 611bc2c4f9649b2c6fe4007f,
bankId: 'string',
mask: '0000',
name: 'Plaid Checking',
userId: 611bc2794d9f391bf2cd7877,
accountNumber: 'xxxxxxxxxxxxxxxxxxx',
bankTokenId: xxxxxxxxxxxxxxxxxxxxxxxxxxx,
createdAt: 2021-08-17T14:08:04.058Z,
isConnected: true,
subtype: 'checking',
type: 'depository',
updatedAt: 2021-08-25T11:36:37.824Z,
isActive: 1,
bankbalance: 
  _id: 61262b9bf9649b2c6fe7d67c,
  ISODate: '2021-05-19T00:00:00.000Z',
  account_id: 'xxxxxxxxxxxxxxxxxxxxxxxx',
  userId: 611bc2794d9f391bf2cd7877,
  ISOCountryCode: null,
  accountId: xxxxxxxxxxxxxxxxxxxx,
  amount: -1047.62,
  bankTokenId: xxxxxxxxxxxxxxxxxxxx,
  createdAt: 2021-08-25T11:37:26.960Z,
  current: null,
  date: '2021-05-19',
  institutionId: xxxxxxxxxxxxxxxxxxxxxx,
  isActive: 1,
  unofficialCountryCode: null,
  updatedAt: 2021-08-25T11:37:26.960Z
 
,

_id: 611bc2c4f9649b2c6fe4007f,
bankId: 'string',
mask: '0000',
name: 'Plaid Checking',
userId: 611bc2794d9f391bf2cd7877,
accountNumber: 'xxxxxxxxxxxxxxxxxxx',
bankTokenId: xxxxxxxxxxxxxxxxxxxxxxxxxxx,
createdAt: 2021-08-17T14:08:04.058Z,
isConnected: true,
subtype: 'checking',
type: 'depository',
updatedAt: 2021-08-25T11:36:37.824Z,
isActive: 1,
bankbalance: 
  _id: 61262b99f9649b2c6fe7d671,
  ISODate: '2021-05-24T00:00:00.000Z',
  account_id: 'xxxxxxxxxxxxxxxxxxxxxxxx',
  userId: 611bc2794d9f391bf2cd7877,
  ISOCountryCode: null,
  accountId: xxxxxxxxxxxxxxxxxxxx,
  amount: -1137.02,
  bankTokenId: xxxxxxxxxxxxxxxxxxxx,
  createdAt: 2021-08-25T11:37:26.960Z,
  current: null,
  date: '2021-05-24',
  institutionId: xxxxxxxxxxxxxxxxxxxxxx,
  isActive: 1,
  unofficialCountryCode: null,
  updatedAt: 2021-08-25T11:37:26.960Z
 

这是一次又一次地给出所有数据记录,这里2个集合之间的引用是accountNumber和account_id。我想将所有记录分组为 1 喜欢


_id: 611bc2c4f9649b2c6fe4007f,
bankId: 'string',
mask: '0000',
name: 'Plaid Checking',
userId: 611bc2794d9f391bf2cd7877,
accountNumber: 'xxxxxxxxxxxxxxxxxxx',
bankTokenId: xxxxxxxxxxxxxxxxxxxxxxxxxxx,
createdAt: 2021-08-17T14:08:04.058Z,
isConnected: true,
subtype: 'checking',
type: 'depository',
updatedAt: 2021-08-25T11:36:37.824Z,
isActive: 1,
bankbalance: [
  _id: 61262b99f9649b2c6fe7d671,
  ISODate: '2021-05-24T00:00:00.000Z',
  account_id: 'xxxxxxxxxxxxxxxxxxxxxxxx',
  userId: 611bc2794d9f391bf2cd7877,
  ISOCountryCode: null,
  accountId: xxxxxxxxxxxxxxxxxxxx,
  amount: -1137.02,
  bankTokenId: xxxxxxxxxxxxxxxxxxxx,
  createdAt: 2021-08-25T11:37:26.960Z,
  current: null,
  date: '2021-05-24',
  institutionId: xxxxxxxxxxxxxxxxxxxxxx,
  isActive: 1,
  unofficialCountryCode: null,
  updatedAt: 2021-08-25T11:37:26.960Z
 ,
 
  _id: 61262b9bf9649b2c6fe7d67c,
  ISODate: '2021-05-19T00:00:00.000Z',
  account_id: 'xxxxxxxxxxxxxxxxxxxxxxxx',
  userId: 611bc2794d9f391bf2cd7877,
  ISOCountryCode: null,
  accountId: xxxxxxxxxxxxxxxxxxxx,
  amount: -1047.62,
  bankTokenId: xxxxxxxxxxxxxxxxxxxx,
  createdAt: 2021-08-25T11:37:26.960Z,
  current: null,
  date: '2021-05-19',
  institutionId: xxxxxxxxxxxxxxxxxxxxxx,
  isActive: 1,
  unofficialCountryCode: null,
  updatedAt: 2021-08-25T11:37:26.960Z
 
]

还可以按日期对银行余额进行排序。任何帮助!提前致谢!!

【问题讨论】:

【参考方案1】:

阶段是按顺序排列的

aggregate.push(lookup);
aggregate.push(unwind);
aggregate.push(group);
aggregate.push(match);

当小组阶段执行时,每个文档将仅包含该阶段中记录的字段。即


  _id: 611bc2c4f9649b2c6fe4007f,
  accountNumber: 'xxxxxxxxxxxxxxxxxxx',
  balances: [ date: ......, amount: ..... ]

执行匹配阶段时,"bankbalance.date"userIdisActivetype 字段不存在,因此没有满足匹配的文档。

【讨论】:

谢谢乔,但我使用的是相同的顺序。我需要将所有记录分组到余额下的一个记录中。无论我写什么都行不通。 您需要在分组之前进行匹配,或者将匹配阶段更改为仅检查分组后实际存在的字段。 谢谢乔,这很有效 const group = $group: _id: '$accountNumber', balances: $addToSet: date: "$bankbalance.date", amount: "$bankbalance.金额" , , , ; 在分组之前排序可能是最简单的。 const sort = $sort: "bankbalance.date": -1 ;我在小组之前使用过这个,但它不起作用

以上是关于$group 和 $lookup 没有提供正确的数据的主要内容,如果未能解决你的问题,请参考以下文章

Mongodb 聚合 $lookup 和 group 非常非常慢

MongoDB $lookup 和 $group 返回空数组

MongoDB 聚合 $lookup 不适用于 $group

Mongoose.aggregate(pipeline) 使用 $unwind、$lookup、$group 链接多个集合

为啥 re.groups() 不为我的一个正确匹配的组提供任何东西?

dapper 多对多查询对象和对象列表