Mongodb использует $ lookup для поиска объекта, которому принадлежит данный _id (внешнее поле является массивом) - PullRequest
0 голосов
/ 26 января 2020

Учитывая следующие коллекции:

пользователь

{
  _id : ObjectId("5e2b9ab8b1dbae5124e4b635")
  name : "user1"
}

{
  _id : ObjectId("5e2b9c29b1dbae5124e4b63b")
  name : "user2"
}

{
  _id : ObjectId("5e2b9cd2b1dbae5124e4b641")
  name : "user3"
}

{
  _id : ObjectId("5e2ba081b1dbae5124e4b64c")
  name : "user4"
}

business_account :

{
  _id : 5e2c5e433e8d406769286567
  name : "account1"
  users : [ObjectId("5e2b9cd2b1dbae5124e4b641"), ObjectId("5e2b9c29b1dbae5124e4b63b")]
}

{
  _id : 4e2c5e433e8d40676928bb43
  name : "account2"
  users : [ObjectId("5e2b9ab8b1dbae5124e4b635")]
}

Мне нужно определить, к какой business_account принадлежит каждый пользователь. (желаемый результат ниже)

{
  _id : ObjectId("5e2b9ab8b1dbae5124e4b635")
  name : "user1"
  belongs_to : "account2"
}

{
  _id : ObjectId("5e2b9c29b1dbae5124e4b63b")
  name : "user2"
  belongs_to : "account1"
}

{
  _id : ObjectId("5e2b9cd2b1dbae5124e4b641")
  name : "user3"
  belongs_to : "account1"
}

{
  _id : ObjectId("5e2ba081b1dbae5124e4b64c")
  name : "user4"
}

Я видел много примеров в inte rnet, говорящих об использовании $ lookup / let / pipeline, но я не понял, как его использовать для получения результатов.

Ниже запроса, который я пытался.

db.user.aggregate([
  {'$lookup': 
    {
      'from': 'business_account',
      'let': { 'profile_id' : '$profile.profile_id' },
      'pipeline' : [
        { "$match": { "$expr": { "$in": ["$$profile_id", "$users"] } } },
      ],
      'as': 'account'
    }
  }
]);

1 Ответ

0 голосов
/ 26 января 2020

Попробуйте:

db.user.aggregate([
    {
        '$lookup':
        {
            'from': 'business_account',
            'let': { 'id': '$_id' }, // Here let is used to create local variable of user collection
            'pipeline': [
                { "$match": { "$expr": { "$in": ["$$id", "$users"] } } }
                , { "$project": { name: 1, _id: 0 } } // Projecting only name
            ],
            'as': 'belongs_to'
        }
    }, { $unwind: { path: "$belongs_to", preserveNullAndEmptyArrays: true } }, // unwinding belongs_to array($lookup will result in array) to object
    { $addFields: { belongs_to: '$belongs_to.name' } } /** Replacing "belongs_to" : { "name": "account2"} to "belongs_to" : "account2" */
])

Тест: MongoDB-Playground

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...