2016-07-29 1 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 

Причина, почему существует несколько версий одного и того же документа, потому что я хочу, чтобы сохранить каждую итерацию сделки. В первый раз, когда я получаю документ, он может быть в transaction_status из UNPAID, тогда я получаю ту же транзакцию снова, и на этот раз transaction_status ПЛАТ.

Некоторый анализ будет заключаться в SUM всех уникальных транзакциях, тогда как другой анализ может заключаться в измерении расстояния между документом со статусом 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" 
    } 
} 
} 

Спасибо за вашу поддержку, Matt

+0

POST ваш демо-документ здесь. – 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_reference и object_creation_date, как я думаю, что было бы целесообразно создать составной индекс на обоих из них вместо даты создания. Отрегулируйте это в соответствии с вашими индексами так, чтобы $sort ударил один.
Кроме того, не было поля документа transaction_sale_value, следовательно, null для него в результате. Возможно, вы пропустили это, или это просто не в ваших образцовых документах, но я думаю, вы поняли, что можете приспособить его к вашим потребностям.

+0

похоже, что он делает то, что говорит на олове, спасибо. Вы правы, это '' transaction_gross_value'', а не 'transaction_sale_value', мой плохой. Теперь я вижу, как все работает - это потрясающе. Я предполагаю, что я могу также использовать $ last вместо $ first, чтобы в итоге я получил первую и последнюю записи, которые будут использоваться в вычислении для измерения разницы во времени между ними. В очередной раз благодарим за помощь –