Как конвейер для документа - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть коллекция с такими документами:

{ "_id" : ObjectId("5b91035eca4f00000124e1d8"), "status" : 0, "date" : NumberLong(0), "players" : [ { "name" : "Valentin", "sets" : [ { "points" : [ { "score" : 0, "comment" : "" }, { "score" : 0, "comment" : "" }, { "score" : 0, "comment" : "" }, { "score" : 1, "comment" : "sa" }, { "score" : 1, "comment" : "" }, { "score" : 1, "comment" : "" }, { "score" : 1, "comment" : "" }, { "score" : 1, "comment" : "" }, { "score" : 1, "comment" : "" }, { "score" : 1, "comment" : "" }, { "score" : 2, "comment" : "" }, { "score" : 2, "comment" : "" }, { "score" : 2, "comment" : "" }, { "score" : 2, "comment" : "" }, { "score" : 3,"comment" : "sw" }, { "score" : 3, "comment" : "" }, { "score" : 3, "comment" : "" }, { "score" : 4, "comment" : "sa" }, { "score" : 5, "comment" : "bh" }, { "score" : 5, "comment" : "" }, { "score" : 5, "comment" : "" }, { "score" : 6, "comment" : "fh" }, { "score" : 6, "comment" : "" }, { "score" : 7, "comment" : "sw" }, { "score" : 7, "comment" : "" }, { "score" : 7, "comment" : "" }, { "score" : 8, "comment" : "" }, { "score" : 8, "comment" : "" }, { "score" : 9, "comment" : "bh" }, { "score" : 10, "comment" : "sw" }, { "score" : 11, "comment" : "sw" } ] } ] }, { "name" : "Zalupkin", "sets" : [ { "points" : [ { "score" : 0, "comment" : "" }, { "score" : 1, "comment" : "" }, { "score" : 2, "comment" : "" }, { "score" : 2, "comment" : "" }, { "score" : 3, "comment" : "fh"}, { "score" : 4, "comment" : "sw" }, { "score" : 5, "comment" : "" }, { "score" : 6, "comment" : "" }, { "score" : 7, "comment" : "" }, { "score" : 8, "comment" : "sa" }, { "score" : 8, "comment" : "" }, { "score" : 9, "comment" : "fh" }, { "score" : 10, "comment" : "sa" }, { "score" : 11, "comment" : "bh" }, {"score" : 11, "comment" : "" }, { "score" : 12, "comment" : "" }, { "score" : 13, "comment" : "" }, { "score" : 13, "comment" : "" }, { "score" : 13, "comment" : "" }, { "score" : 14, "comment" : "" }, { "score" : 15, "comment" : "sa" }, { "score" : 15, "comment" : "" }, { "score" : 16, "comment" : "sw" }, { "score" : 16, "comment" : "" }, { "score" : 17, "comment" : "" }, { "score" : 18, "comment" : "" }, { "score" : 18, "comment" : "" }, { "score" : 19, "comment" : "sa" }, { "score" : 19, "comment" : "" }, { "score" : 19, "comment" : "" }, { "score" : 19, "comment" : "" } ] } ] } ] }

Я попытался создать конвейер агрегации, чтобы посчитать, как в гривенном комментарии "sw" есть игрок с именем "Valentin".

Также этоможет быть во многих документах, и мне нужно сосчитать целые комментарии.

Результат должен выглядеть примерно так: {"_id": null, "count": 0}

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Вы можете попробовать ниже агрегации.

Начальный $filter для фильтрации для соответствующего игрока и затем $filter для фильтрации точек, где комментарий = 'sw', за которым следует $size для подсчета совпадений в каждом массиве точек. Используйте $map для выполнения логики для всех наборов и $sum для расчета всех совпадений для всех наборов

$group для подсчета совпадений во всех документах.

db.colname.aggregate([
  {"$match":{"players.name":"Valentin"}},
  {"$project":{
    "count":{
      "$sum":{
        "$map":{
          "input":{
            "$let":{
              "vars":{
                "mplayer":{
                  "$filter":{"input":"$players","as":"player","cond":{"$eq":["$$player.name","Valentin"]}
                 }
                }
              },
              "in":{"$arrayElemAt":["$$mplayer.sets",0]}
            }
          },
          "as":"set",
          "in":{
            "$size":{
              "$filter":{"input":"$$set.points","cond":{"$eq":["$$this.comment","sw"]}}
            }
          }
        }
      }
    }
  }},
  {"$group":{"_id":null,"count":{"$sum":"$count"}}}
])
0 голосов
/ 06 сентября 2018

Может быть, это работает:

db.getCollection('test2').aggregate([
// Target only the documents which contains player Valentin

{ $match: {"players.name" : "Valentin"}},

//Unwind the array players so we can remove the part from the other players
{ $unwind: "$players"},

//Get the players whose name is Valentin of the unwind set
{ $match: {"players.name" : "Valentin"}},

//Reduce the deep of the array so we can count them well
{ $project: {"points": "$players.sets.points"}},
{ $unwind: "$points"},
{ $unwind: "$points"},

//Query of comment match
{ $match: {"points.comment" : "sw" }},

//Calculate count
{ $group: {
    _id: null,
    count: { $sum: 1 }
    }}
])
...