Подсчет как внешнего, так и внутреннего встроенного массива в одном запросе - PullRequest
1 голос
/ 03 ноября 2019
{
_id: ObjectId("5dbdacc28cffef0b94580dbd"),
 "comments" : [
     {
      "_id" : ObjectId("5dbdacc78cffef0b94580dbf"),
      "replies" : [
                   {
                     "_id" : ObjectId("5dbdacd78cffef0b94580dc0")          
                   },
                 ]
     },
  ]
}

Как подсчитать количество элементов в comments и сумму с числом relies

Мой подход - сделать запрос 2 следующим образом:

1. Всего элементов replies

db.posts.aggregate([
{$match: {_id:ObjectId("5dbdacc28cffef0b94580dbd")}},

{ $unwind: "$comments",},

{$project:{total:{$size:"$comments.replies"} , _id: 0} }

])

2. подсчитать общее количество элементов комментариев

db.posts.aggregate([
{$match: {_id:ObjectId("5dbdacc28cffef0b94580dbd")}},
{$project:{total:{$size:"$comments.replies"} , _id: 0} }

])

Затем суммировать оба, есть ли у нас лучшее решение для написания запроса, например, вернуть сумму общего элемента comments + replies

Ответы [ 3 ]

2 голосов
/ 03 ноября 2019

Вы можете использовать $reduce и $concatArrays в «объединить» внутренний «массив массивов» в один список и измерить $size этого. Затем просто $add два результата вместе:

db.posts.aggregate([
  { "$match": { _id:ObjectId("5dbdacc28cffef0b94580dbd") } },
  { "$addFields": {
    "totalBoth": {
      "$add": [
        { "$size": "$comments" },
        { "$size": {
          "$reduce": {
            "input": "$comments.replies",
            "initialValue": [],
            "in": {
              "$concatArrays": [ "$$value", "$$this" ] 
            }
          }
        }}
      ]
    }
  }}
])

Отметив, что «массив массивов» является эффектом выражения, подобного $comments.replies, поэтому, следовательно, операция дляони в один массив, где вы можете измерить все элементы.

0 голосов
/ 09 ноября 2019

Это еще один способ получения результата.

Входные документы:

{ "_id" : 1, "array1" : [ { "array2" : [ { id: "This is a test!"}, { id: "test1" } ] }, { "array2" : [ { id: "This is 2222!"}, { id: "test 222" }, { id: "222222" } ] } ] }
{ "_id" : 2, "array1" : [ { "array2" : [ { id: "aaaa" }, { id: "bbbb" } ] } ] }


Запрос:

db.arrsizes2.aggregate( [
  { $facet: {
     array1Sizes: [
          { $project: { array1Size: { $size: "$array1" } } }
     ],
     array2Sizes: [
          { $unwind: "$array1" },
          { $project: { array2Size: { $size: "$array1.array2" } } },
     ],
  } },
  { $project: { result: { $concatArrays: [ "$array1Sizes", "$array2Sizes" ] } } },
  { $unwind: "$result" },
  { $group: { _id: "$result._id", total1: { $sum: "$result.array1Size" }, total2: { $sum: "$result.array2Size" } } },
  { $addFields: { total: { $add: [ "$total1", "$total2" ] } } },
] )


Выходные данные:

{ "_id" : 2, "total1" : 1, "total2" : 2, "total" : 3 }
{ "_id" : 1, "total1" : 2, "total2" : 5, "total" : 7 }
0 голосов
/ 03 ноября 2019

Попробуйте использовать $unwind, чтобы сгладить список, полученный из $project перед использованием $count.

...