Возврат документов, соответствующих набору результатов подзапроса - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь решить проблему, которая в Sql Server потребовала бы общего табличного выражения или подзапроса.

У меня есть коллекция с именем Invoice_Details. Каждый документ имеет поля InvoiceID, CustomerID, TransactionDate и TransactionAmount.

Что я хочу сделать, так это вернуть весь документ, который при агрегировании TransactionAmount не равен нулю.

Я делаю группировку следующим образом:

   db.Invoice_Details.aggregate(
   [
     {
       $group:
         {
           _id: { InvoiceID: "$InvoiceID"},
           Balance: { $sum: "$TransactionAmount"}
         }
     },
     { $match: { Balance: { $ne: 0 } } }
   ]
)

и это дает

{
    "_id" : {
        "InvoiceID" : "234904"
    },
    "Balance" : 182.67
}

.... сотни дополнительных документов, это здорово.

Теперь я хочу получить все документы invoice_details, которые были возвращены в совокупности.

В Sql Server я бы присоединился к результатам общего табличного выражения / подзапроса, но я не уверен, как (если?) Я могу это сделать.

1 Ответ

0 голосов
/ 04 мая 2018

Ну, вы могли бы сделать "$lookup" на основе "InvoiceID" и сразу $unwind результатов, на случай, если речь идет о достаточно больших результатах документа, которые могут фактически нарушает лимит BSON;

db.Invoice_Details.aggregate([
  { "$group": {
    "_id": "$InvoiceID",
    "balance": { "$sum": "$TransactionAmount" }
  }},
  { "$match": { "balance": { "$ne": 0 } } },
  { "$lookup": {
    "from": "Invoice_Details",
    "localField": "_id",
    "foreignField": "InvoiceID",
    "as": "details"
  }},
  { "$unwind": "$details" },
  { "$replaceRoot": { "newRoot": "$details" } }
])

В идеале вы должны $replaceRoot здесь, чтобы просто продвинуть поле со всеми результатами в корень документа. В противном случае используйте $project и назовите все поля, если ваша версия MongoDB меньше 3.4 и не имеет стадии конвейера:

  { "$project": {
    "_id": "$details._id",
    "InvoiceID": "$details.InvoiceID",
    "CustomerID": "$details.CustomerID",
    "TransactionDate": "$details.TransactionDate",
    "TransactionAmount": "$details.TransactionAmount"
  }}

Но, по сути, выполнение "$lookup" здесь фактически является «подзапросом» и условием соединения для "InvoiceID", просто MongoDB представляет его в другом порядке. Так что «последовательно», как «сначала агрегат», затем присоединяйтесь.

...