Порядок:

{
  order_id: 1,
  order_time: ISODate(...),
  customer_id: 456,
  products: [
    {
      product_id: 1,
      product_name: "Pencil"
    },
    {
      product_id: 2,
      product_name: "Scissors"
    },
    {
      product_id: 3,
      product_name: "Tape"
    }
  ]
}

У меня есть коллекция с целым набором документов, подобных вышеупомянутому. Я хотел бы запросить последний заказ для каждого клиента, заказавшего ножницы.

То есть, если существует «products.product_name», равное «Scissors», сгруппируйте по customer_id, дайте мне полный документ, где «order_time» - это «максимум» для этой группы.

Чтобы найти документы, я мог бы сделать что-то вроде find({ 'products.product_name' : "Scissors" }), но потом я получаю весь заказ с помощью ножниц, мне нужны только самые свежие.

Итак, я смотрю на агрегацию ... Стадия агрегации Mongo "$ group", похоже, требует, чтобы вы выполняли какую-то фактическую агрегацию внутри, например sum, max или что-то еще. Я предполагаю, что здесь есть некоторая комбинация $match, $group и $sort, но я не могу заставить ее работать.

Нечто близкое

db.storcap.aggregate(
[
{
  $match: { 'products.product_name' : "Scissors" }
},
{
  $sort: { created_at:-1 }
},
{
  $group: {
    _id: "$customer_id", 
  }
}]
)

Но это не возвращает полный документ, и я не уверен, что он правильно выполняет сортировку и группировку.

2
MichaelB 23 Мар 2019 в 00:03

1 ответ

Лучший ответ

Вы можете использовать оператор $ first, чтобы получить самые последние order (упорядочены по убыванию) и специальная переменная $$ROOT < / a>, чтобы получить в конечном результате весь объект:

db.storcap.aggregate([
    {
        $match: { 'products.product_name' : "Scissors" }
    },
    {
        $sort: { created_at:-1 }
    },
    {
        $group: {
            _id: "$customer_id",
            lastOrder: { $first: "$$ROOT" }
        }
    }
])
1
mickl 22 Мар 2019 в 21:07