2016-07-29 67 views
3

我想查找一個mongoDB腳本,它將查看一個集合,其中有多個相同文檔的記錄,並且僅向我提供每個文檔的最新版本作爲結果集。在mongoDB中按日期查詢文檔的最新版本

我無法用英文解釋它,但可能下面這個小小的SQL可能會進一步解釋它。我想要transaction_reference的每個文件,但只有最新的日期版本(object_creation_date)。

select 
    t.transaction_reference, 
    t.transaction_date, 
    t.object_creation_date, 
    t.transaction_sale_value 
from MyTable t 
inner join (
    select 
     transaction_reference, 
     max(object_creation_date) as MaxDate 
    from MyTable 
    group by transaction_reference 
) tm 
    on t.transaction_reference = tm.transaction_reference 
    and t.object_creation_date = tm.MaxDat 

爲什麼存在同一文檔的多個版本的原因是因爲我想存儲每個事務的迭代。我第一次收到一份文件,它可能在UNPAID的transaction_status,然後我再次收到相同的交易,這一次是付費的。

一些分析將彙總所有的唯一交易,而另一些分析可能是衡量狀態爲UNPAID的文檔與下一個PAID之間的時間距離。

根據要求,這裏有兩個文件:

{ 
"_id": { 
    "$oid": "579aa337f36d2808839a05e8" 
}, 
"object_class": "Goods & Services Transaction", 
"object_category": "Revenue", 
"object_type": "Transaction", 
"object_origin": "Sage One", 
"object_origin_category": "Bookkeeping", 
"object_creation_date": "2016-07-05T00:00:00.201Z", 
"party_uuid": "dfa1e80a-5521-11e6-beb8-9e71128cae77", 
"connection_uuid": "b945bd7c-7988-4d2a-92f5-8b50ab218e00", 
"transaction_reference": "SI-1", 
"transaction_status": "UNPAID", 
"transaction_date": "2016-06-16T00:00:00.201Z", 
"transaction_due_date": "2016-07-15T00:00:00.201Z", 
"transaction_currency": "GBP", 
"goods_and_services": [ 
    { 
     "item_identifier": "PROD01", 
     "item_name": "Product One", 
     "item_quantity": 1, 
     "item_gross_unit_sale_value": 1800, 
     "item_revenue_category": "Sales Revenue", 
     "item_net_unit_cost_value": null, 
     "item_net_unit_sale_value": 1500, 
     "item_unit_tax_value": 300, 
     "item_net_total_sale_value": 1500, 
     "item_gross_total_sale_value": 1800, 
     "item_tax_value": 300 
    } 
], 
"transaction_gross_value": 1800, 
"transaction_gross_curr_value": 1800, 
"transaction_net_value": 1500, 
"transaction_cost_value": null, 
"transaction_payments_value": null, 
"transaction_payment_extras_value": null, 
"transaction_tax_value": 300, 
"party": { 
    "customer": { 
     "customer_identifier": "11", 
     "customer_name": "KP" 
    } 
} 
} 

和第二個版本,其中它現在爲你支付支持

{ 
"_id": { 
    "$oid": "579aa387f36d2808839a05ee" 
}, 
"object_class": "Goods & Services Transaction", 
"object_category": "Revenue", 
"object_type": "Transaction", 
"object_origin": "Sage One", 
"object_origin_category": "Bookkeeping", 
"object_creation_date": "2016-07-16T00:00:00.201Z", 
"party_uuid": "dfa1e80a-5521-11e6-beb8-9e71128cae77", 
"connection_uuid": "b945bd7c-7988-4d2a-92f5-8b50ab218e00", 
"transaction_reference": "SI-1", 
"transaction_status": "PAID", 
"transaction_date": "2016-06-16T00:00:00.201Z", 
"transaction_due_date": "2016-07-15T00:00:00.201Z", 
"transaction_currency": "GBP", 
"goods_and_services": [ 
    { 
     "item_identifier": "PROD01", 
     "item_name": "Product One", 
     "item_quantity": 1, 
     "item_gross_unit_sale_value": 1800, 
     "item_revenue_category": "Sales Revenue", 
     "item_net_unit_cost_value": null, 
     "item_net_unit_sale_value": 1500, 
     "item_unit_tax_value": 300, 
     "item_net_total_sale_value": 1500, 
     "item_gross_total_sale_value": 1800, 
     "item_tax_value": 300 
    } 
], 
"transaction_gross_value": 1800, 
"transaction_gross_curr_value": 1800, 
"transaction_net_value": 1500, 
"transaction_cost_value": null, 
"transaction_payments_value": null, 
"transaction_payment_extras_value": null, 
"transaction_tax_value": 300, 
"party": { 
    "customer": { 
     "customer_identifier": "11", 
     "customer_name": "KP" 
    } 
} 
} 

謝謝,馬特

+0

在此處發佈您的演示文檔。 – rroxysam

回答

1

如果我沒有理解問題正確你可以使用類似這樣的東西

db.getCollection('yourTransactionsCollection').aggregate([ 
    { 
     $sort: { 
      "transaction_reference": 1, 
      "object_creation_date": -1 
     } 
    }, 
    { 
     $group: { 
      _id: "$transaction_reference", 
      "transaction_date": { $first: "$transaction_date" }, 
      "object_creation_date": { $first: "$transaction_date" }, 
      "transaction_sale_value": { $first: "$transaction_sale_value" } 
     } 
    } 
]) 

它輸出類似下面

{ 
    "_id" : "SI-1", 
    "transaction_date" : "2016-06-16T00:00:00.201Z", 
    "object_creation_date" : "2016-06-16T00:00:00.201Z", 
    "transaction_sale_value" : null 
} 

注意結果,你可以改變$sort只包括object_creation_date,但我同時transaction_referenceobject_creation_date,我認爲這將是有意義的創建既綜合指數而不僅僅是創建日期。根據您的索引進行調整,以使$sort達到一個。
另外,在結果中沒有文檔域transaction_sale_value,因此null。也許你錯過了這一點,或者它只是不在你的示例文檔中,但我認爲你明白了,並可以根據你的需要進行調整。

+0

這看起來像它所做的一樣,謝謝你。你是對的,它是'transaction_gross_value'而不是'transaction_sale_value',我的不好。我現在看到它的工作原理 - 這很棒。我想我也可以使用$ last而不是$ first,這樣我就可以結束第一個和最後一個記錄 - 用於計算以測量每個記錄之間的時間差。再次感謝你的幫助 –