mongodb - сумма длины массива с одинаковыми идентификаторами - PullRequest
1 голос
/ 05 апреля 2020

Я создаю платформу, где люди могут делиться своими мемами. На одной странице я хочу показать им, кто самые популярные участники на платформе. Итак, существует коллекция 'meme' и 'user'

, например,

. Существует два контента с одинаковыми идентификаторами:

{
  _id: 1,
  username: "name",
  bio: "bio",
  image: "url",
};

memes

{
  _id: 0,
  user_id: 1,
  image: "meme1.jpg",
  likes: [
    {
      user_id: 4
    }
  ]
},
{
  _id: 1,
  user_id: 1,
  image: "meme2.jpg",
  likes: [
    {
      user_id: 5
    },
    {
      user_id: 6
    }
  ]
}

и я хочу вывести что-то вроде этого

{
  user_id:1,
  username:"name"
  likes:3,
}

Я написал этот запрос, используя агрегатные функции, но я не понимаю, как идентифицировать идентификаторы одинаковые или нет?

meme
  .aggregate([
    {
      $lookup: {
        from: "users",
        localField: "user_id",
        foreignField: "_id",
        as: "userDetails",
      },
    },
    {
      $project: {
        user_id: "$user_id",
        username: "$userDetails.username",
        likes: {
          $size: "$likes",
        },
      },
    },
    {
      $sort: { likes: 1 },
    },
  ])
  .exec()
  .then((result) => {
    console.log(result);
  });

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Начать запрос с пользователей будет проще.

Вы можете использовать $ sum , $ map , $ size агрегаты для получить общее количество лайков и добавить его, используя $ addFields .

db.users.aggregate([
  {
    $lookup: {
      from: "memes",
      localField: "_id",
      foreignField: "user_id",
      as: "userDetails"
    }
  },
  {
    $addFields: {
      "likes": {
        "$sum": {
          "$map": {
            "input": "$userDetails",
            "in": {
              "$size": "$$this.likes"
            }
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      user_id: "$_id",
      username: 1,
      likes: 1
    }
  }
])

Детская площадка

Результат:

[
  {
    "likes": 3,
    "user_id": 1,
    "username": "name"
  }
]
1 голос
/ 05 апреля 2020

Вы можете спроецировать длину массива likes, сгруппировать каждую проекцию по user_id и сопоставить результаты. Примерно так должно работать:

db.getCollection('memes').aggregate([{
            $lookup: {
                from: "users",
                localField: "user_id",
                foreignField: "_id",
                as: "userDetails"
            }
        }, {
            "$project": {
                "user_id": 1,
                "likesSize": {
                    "$size": "$likes"
                }
            }
        }, {
            $group: {
                _id: "$user_id",
                "count": {
                    "$sum": "$likesSize"
                }

            }
        }
    ])

Вышеприведенный запрос должен вернуть:

{
    "_id" : 1,
    "count" : 3
}
...