Получить взаимных последователей в мангусте - PullRequest
0 голосов
/ 19 марта 2020

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

пользовательская схема:

let User = new mongoose.Schema({
uid: {
    type: String,
    require: true,
    unique: true
},
    followers: [String],
    following: [String]
})

, где последователи / подписчики - это массив UID

, которые я пробовал это:

let me = await User.findOne({uid: uid})
if (me) {
    console.log(me.followers)
    let mutual = await User.aggregate([
        // Match documents that contain the elements
        { "$match": { 
            "followers": { "$in": me.followers }
        }},

        // // De-normalize the array field content
        { "$unwind": "$followers" },

        // Match just the elements you want
        { "$match": { 
            "followers": { "$in": me.followers }
        }},

        // Count by the element as a key
        { "$group": {
            "_id": "$name",  
            "mutual": { "$sum":  1}
        }}
    ])
    if (mutual) {
        console.log('mutual', mutual)
    }
}

но это не дает правильный счет

1 Ответ

1 голос
/ 19 марта 2020

Вы можете использовать $filter и $size вместо того, чтобы раскручивать подписчиков для каждого человека. Вы также можете сделать это с помощью $lookup вместо 2 запросов на стороне клиента.

Этапы в приведенном ниже конвейере:

  • $ соответствует рассматриваемому пользователю
  • $ lookup извлекает все виды использования, у которых есть общий подписчик, помещая их в массив matched
  • $, раскручивая сопоставленный массив, чтобы рассматривать каждого пользователя отдельно
  • $ match - так как пользователь в вопрос также будет сопоставлен с наличием соответствующего подписчика, исключите эту запись 'self'
  • $ project исключит все поля, кроме uid другого человека, и для фильтра commonFollowers:
    • $ filter итерировать каждый массив лиц followers, сохраняя только те записи, которые соответствуют рассматриваемому пользователю
    • $ size, чтобы вернуть количество оставшихся элементов
[
  {"$match": {"uid": uid}},
  {
    "$lookup": {
      "from": "User",
      "localField": "followers",
      "foreignField": "followers",
      "as": "matched"
  }},
  {"$unwind": "$matched"},
  {"$match": {"$expr": {"$ne": ["$matched.uid", "$uid"]}}},
  {"$project": {
      "_id": 0,
      "uid": "$matched.uid",
      "commonFollowers": {
        "$size": {
          "$filter": {
            "input": "$matched.followers",
            "cond": {
              "$in": [
                "$$this",
                "$followers"
              ]
  }}}}}},
  {"$sort": {"commonFollowers": -1}}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...