coccide Ответов: 1

Получить последнюю стоимость вложенных документов в MongoDB


Всем привет.
Я пытаюсь понять, как я могу извлечь последнее значение, скажем, переменной в наборе документов.
Допустим у меня есть 2 документа:
{ 
   "Name": "doc1", 
   "Date": ISODate("2019-12-31T00:00:00.000Z"),
   "Values" : [
         {
            "VariableName": "VAR1",
            "VariableValue": "VAL1"
         },
         {
            "VariableName": "VAR2",
            "VariableValue": "VAL2"
         } ]
},
{ 
   "Name": "doc2", 
   "Date": ISODate("2020-01-31T00:00:00.000Z"),
   "Values" : [
         {
            "VariableName": "VAR1",
            "VariableValue": "VAL3"
         },
         {
            "VariableName": "VAR3",
            "VariableValue": "VAL3"
         } ]
}



Я хотел бы написать "запрос", который извлекает только последнее значение каждой переменной:

{ 
   "Document": "doc2", 
   "Date": ISODate("2020-01-31T00:00:00.000Z"),
   "VariableName", "VAR1",
   "VariableValue", "VAL3"
},
{
   "Document": "doc1", 
   "Date": ISODate("2019-12-31T00:00:00.000Z"),
   "VariableName", "VAR2",
   "VariableValue", "VAL2"
},
{ 
   "Document": "doc2", 
   "Date": ISODate("2020-01-31T00:00:00.000Z"),
   "VariableName", "VAR3",
   "VariableValue", "VAL3"
}


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

Может кто-нибудь помочь, пожалуйста?

Что я уже пробовал:

//Prepare documents
var o = [
{ 
   "Name": "doc1", 
   "Date": ISODate("2019-12-31T00:00:00.000Z"),
   "Values" : [
         {
            "VariableName": "VAR1",
            "VariableValue": "VAL1"
         },
         {
            "VariableName": "VAR2",
            "VariableValue": "VAL2"
         } ]
},
{ 
   "Name": "doc2", 
   "Date": ISODate("2020-01-31T00:00:00.000Z"),
   "Values" : [
         {
            "VariableName": "VAR1",
            "VariableValue": "VAL3"
         },
         {
            "VariableName": "VAR3",
            "VariableValue": "VAL3"
         } ]
}
];

//Insert objects
db.getCollection("docs").insertMany(o);

//Flattening I get
db.docs.aggregate(
[
   { "$unwind" : "$Values" },
   { "$project": { "Name": 1, "Date" : 1, "VariableName": "$Values.VariableName", "VariableValue": "$Values.VariableValue" } }
]
).pretty();

{
        "_id" : ObjectId("5e96d8632f441e3738a0ff2f"),
        "Name" : "doc1",
        "Date" : ISODate("2019-12-31T00:00:00Z"),
        "VariableName" : "VAR1",
        "VariableValue" : "VAL1"
}
{
        "_id" : ObjectId("5e96d8632f441e3738a0ff2f"),
        "Name" : "doc1",
        "Date" : ISODate("2019-12-31T00:00:00Z"),
        "VariableName" : "VAR2",
        "VariableValue" : "VAL2"
}
{
        "_id" : ObjectId("5e96d8632f441e3738a0ff30"),
        "Name" : "doc2",
        "Date" : ISODate("2020-01-31T00:00:00Z"),
        "VariableName" : "VAR1",
        "VariableValue" : "VAL3"
}
{
        "_id" : ObjectId("5e96d8632f441e3738a0ff30"),
        "Name" : "doc2",
        "Date" : ISODate("2020-01-31T00:00:00Z"),
        "VariableName" : "VAR3",
        "VariableValue" : "VAL3"
}

//Then I need to find latest value bye date and VariableName
db.docs.aggregate(
[
   { "$unwind" : "$Values" },
   { "$project": { "Name": 1, "Date" : 1, "VariableName": "$Values.VariableName", "VariableValue": "$Values.VariableValue" } },
   { "$group": { _id : { "VariableName": "$VariableName"}, latest: {"$max" : "$Date"} } }
]
).pretty();

{
        "_id" : {
                "VariableName" : "VAR3"
        },
        "latest" : ISODate("2020-01-31T00:00:00Z")
}
{
        "_id" : {
                "VariableName" : "VAR2"
        },
        "latest" : ISODate("2019-12-31T00:00:00Z")
}
{
        "_id" : {
                "VariableName" : "VAR1"
        },
        "latest" : ISODate("2020-01-31T00:00:00Z")
}

1 Ответов

Рейтинг:
0

coccide

Хорошо Мне удалось получить то, что я хочу, используя некоторые промежуточные объекты представления, но я думаю, что должен быть более элегантный способ сделать это:

var tutti = db.createView(
"tutti",
"docs",
[
   { "$unwind" : "$Values" },
   { "$project": { "Name": 1, "Date" : 1, "VariableName": "$Values.VariableName", "VariableValue": "$Values.VariableValue" } }
]
);

db.ultimeModifiche.drop();
var ultimeModifiche = db.createView(
"ultimeModifiche",
"tutti",
[
   { "$group": { _id : { "VariableName": "$VariableName"}, latest: {"$max" : "$Date"} } },
   { "$project": { "VariableName": "$_id.VariableName", "latest": 1, _id:0 } }
]
);


db.ultimiValori.drop();
var ultimiValori = db.createView(
"ultimiValori",
"ultimeModifiche",
[
   { 
      "$lookup": 
      { 
	     from : "tutti",
		 let: {
                variableName: "$VariableName",
                latest: "$latest"
             },
		 pipeline: [
                {
                   $match: {
                      $expr: {
                         $and: [
                            {
                               $eq: [
                                  "$VariableName",
                                  "$$variableName"
                               ]
                            },
                            {
                               $eq: [
                                  "$Date",
                                  "$$latest"
                               ]
                            }
                         ]
                      }
                   }
                }
             ],
		 as: "output"
	   }
   },   
    {
      $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$output", 0 ] }, "$$ROOT" ] } }
   },
   { $project: { output: 0 } }
   
]
);
db.ultimiValori.find();