【问题标题】:MongoDB Query unique values by other fieldsMongoDB 按其他字段查询唯一值
【发布时间】:2020-05-06 21:38:20
【问题描述】:

td;rd

我想获取所有交易并忽略pendingTransactionId字段等于另一个文档的transactionId的交易。


我有一个名为 Transactions 的集合,我存储代表诸如银行交易之类的交易的文档。这些事务有一个标志,告诉您它是否处于挂起状态,以及一个存储挂起事务 ID 的字段。这是一个例子:

// Pending Transaction
{
  transactionId: 1,
  pending: true,
  pendingTransactionId: null,
  amount: 5
}

// Processed transaction
{
  transactionId: 2,
  pending: false,
  pendingTransactionId: 1,
  amount: 7
}

这些是“相同”的交易,但我有 2 条记录,因为已处理的交易可能会在不同的时间处理(例如待处理交易完成后的 1 或 2 天),并且有些字段可能会更改,比如amount(例如,这可能是我在餐厅留下的小费)。

我正在尝试创建并且遇到困难的查询是会给我所有事务但它会忽略“重复”的查询:如果 pendingTransactionId 等于 transactionId 则应该忽略事务另一个文件。


更新

添加记录与预期的示例

// records
{
  transactionId: 123,
  pending: true,
  pendingTransactionId: null,
  amount: 5
}
{
  transactionId: 321,
  pending: false,
  pendingTransactionId: 123,
  amount: 7
}
{
  transactionId: 333,
  pending: false,
  pendingTransactionId: 888,
  amount: 22
}
{
  transactionId: 444,
  pending: true,
  pendingTransactionId: null,
  amount: 50
}
{
  transactionId: 555,
  pending: false,
  pendingTransactionId: null,
  amount: 60
}
// expected
{
  transactionId: 321,
  pending: false,
  pendingTransactionId: 123,
  amount: 7
}
{
  transactionId: 333,
  pending: false,
  pendingTransactionId: 888,
  amount: 22
}
{
  transactionId: 444,
  pending: true,
  pendingTransactionId: null,
  amount: 50
}
{
  transactionId: 555,
  pending: false,
  pendingTransactionId: null,
  amount: 60
}

transactionId=123 的记录被忽略,因为已经有一个事务已处理(待处理=false)。 transactionId=333 不会被忽略,因为它不是待处理的,即使我们没有待处理事务的记录

【问题讨论】:

  • 您能否发布更多示例。需要看看我们是否可以通过$graphLookup 得到想要的结果
  • @Valijon 添加了一个示例

标签: mongodb mongoose mongodb-query


【解决方案1】:

我想获取所有交易并忽略其中的交易 pendingTransactionId 字段等于另一个的 transactionId 文件。

这是一个自我查找操作。查找具有父事务(pendingTransactionId 的事务)的所有事务,作为每个文档的结果数组。然后在下一阶段删除所有带有父事务的文档。在示例文档中,transactionId: 123 与父 transactionId: 321 匹配。

db.test.aggregate( [
 {
    $lookup: {
        from: "txns",
        localField: "transactionId",
        foreignField: "pendingTransactionId",
        as: "parent_txn"
    }
 },
 {
    $match: { parent_txn: { $size: 0 } }
 },
 { 
    $project: { parent_txn: 0 }
 }
] )

【讨论】:

    【解决方案2】:

    没有任何原生解决方案...

    1. 但是,我们可以使用$lookup 运算符将left join 与自身结合起来,通过组合transactionIdpendingTransactionId 字段来匹配文档

    我们可能会得到:

    a) doc{ pending = false, transaction : [{pending: true}]  } ✔
    b) doc{ pending = true,  transaction : [{pending: false}] } X
    c) doc{ pending = false, transaction : []               } ✔
    
    1. 下一阶段,我们过滤带有内部数组transaction.pending = true 或空transaction 的文档。

    2. 使用$unset,我们从结果文档中排除字段。


    db.collection.aggregate([
      {
        $lookup: {
          from: "collection",
          let: {
            transactionId: "$transactionId",
            pendingTransactionId: "$pendingTransactionId"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $or: [
                    {
                      $eq: [
                        "$$transactionId",
                        "$pendingTransactionId"
                      ]
                    },
                    {
                      $eq: [
                        "$transactionId",
                        "$$pendingTransactionId"
                      ]
                    }
                  ]
                }
              }
            }
          ],
          as: "transactions"
        }
      },
      {
        $match: {
          $expr: {
            $or: [
              {
                $eq: [
                  {
                    $let: {
                      vars: {
                        transaction: {
                          $arrayElemAt: [
                            "$transactions",
                            0
                          ]
                        }
                      },
                      in: "$$transaction.pending"
                    }
                  },
                  true
                ]
              },
              {
                $eq: [
                  {
                    $size: "$transactions"
                  },
                  0
                ]
              }
            ]
          }
        }
      },
      {
        $unset: "transactions"
      }
    ])
    

    MongoPlayground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-14
      • 2018-12-01
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      相关资源
      最近更新 更多