简体   繁体   English

MongoDB查询联接两个集合

[英]Mongodb query join two collections

I´m trying to make a query to my bbdd in order to get some info that involve two collections. 我正在尝试对bbdd进行查询,以获得一些涉及两个集合的信息。 First, I have one collecction, called Collectables that is a collection that store all available items that One user can get using an App. 首先,我有一个集合,称为Collectables,它是一个集合,存储一个用户可以使用App获得的所有可用项目。 For example, this collection can have... 100 items. 例如,此收藏集可以有... 100个项目。 This is the maximum number of items. 这是最大项目数。 This is one document of this collection (called collectables) 这是此收藏的一个文件(称为收藏品)

{
"_id" : ObjectId("5d387ecfbb676b173aa57fe3"),
"img" : "some url",
"name" : "La 5",
"__v" : 0,
"amount" : 17,
"available" : 16,
"collec" : ObjectId("5d36c0c34c86991db93bd7c8"),
"gen" : 3,
"metadata" : {},
"position" : 1
}

Then, I have another collection called AppUsers. 然后,我有了另一个名为AppUsers的集合。 In this collection I store all info related to the user. 在此集合中,我存储了与用户有关的所有信息。 Each user of the App has his own record here. 该应用程序的每个用户在这里都有自己的记录。 The point is that besides meta info of the user such alias, avatar, age... I have one field called collectables. 关键是,除了用户的别名,头像,年龄等元信息外,我还有一个字段称为collectables。 Is an array. 是一个数组。 Here I store what collectable have each user. 在这里,我存储了每个用户可以收集的东西。 For example, if one user have 10 collectables (from the other collection) I have 10 entries in this array with that info. 例如,如果一个用户有10个收藏品(来自另一个收藏品),则此数组中有10个条目包含该信息。 Is possible that one user "win" the same item (collectable) twice or more.. so in this collection I store a count field with the total. 一个用户有可能两次(两次以上)“赢得”相同的项目(可收集),所以在此集合中,我存储了总数的计数字段。 For example, a user win the collectable with Id 1 the first time, so I add the entry in the array with count 1. If then the user win the same collectable, the count is 2... and so on. 例如,一个用户第一次赢得ID为1的可收集项,因此我在计数为1的数组中添加了该条目。如果该用户赢得了相同的收集项,则计数为2 ...依此类推。

This is an example of one user... with 3 collectables, but several number of each item. 这是一个用户的示例……拥有3个收藏品,但每个项目都有多个。

{
"_id" : ObjectId("5d36dc9445526a215c4eff52"),
"twitter" : "1",
"alias" : "ViktorCrowley",
"__v" : 25,
"collectables" : [ 
    {
        "count" : 12,
        "collectable" : ObjectId("5d36c1ba4c86991db93bd7e7")
    }, 
    {
        "count" : 25,
        "collectable" : ObjectId("5d36c13d4c86991db93bd7c9")
    }, 
    {
        "count" : 8,
        "collectable" : ObjectId("5d381e122f25221126a98f9c")
    }
   ]
}

So, in this case, this user, for example have 3 differents items (collectables). 因此,在这种情况下,该用户例如具有3个不同的项目(收藏品)。 But imagine that the total of collectables from the first collection is 100. 但是想象一下,第一个收藏品的收藏品总数为100。

Now... what I´m looking for. 现在...我在寻找什么。 I need a query that give me (paginated) the items from the first collection (collectables) and in the case that the user already have one of this items, marked with the total count. 我需要一个查询,该查询将给我(分页)第一个集合(收藏品)中的项目,并且在用户已经拥有其中一个项目的情况下,用总计数标记。 I mean, I want all the items from the first collection, with a new field, called count. 我的意思是,我希望第一个集合中的所有项目都有一个新字段,称为count。 If the user doens´t have any entry in his array, count will be 0, and if the user for that item, has for example 4 collectables, the count will be 4. Some thing like this: 如果用户在其数组中没有任何条目,则计数将为0,并且如果该项目的用户具有例如4个收藏品,则计数将为4。

[
{
"_id" : ObjectId("5d387ecfbb676b173aa57fe3"),
"img" : "some url",
"name" : "THe one",
"__v" : 0,
"amount" : 17,
"available" : 16,
"collec" : ObjectId("5d36c0c34c86991db93bd7c8"),
"gen" : 3,
"metadata" : {},
"position" : 1,
"count" : 0
},
{
"_id" : ObjectId("5d387ecfbb676b173aa57fe3"),
"img" : "some url",
"name" : "The two",
"__v" : 0,
"amount" : 17,
"available" : 16,
"collec" : ObjectId("5d36c0c34c86991db93bd7c8"),
"gen" : 3,
"metadata" : {},
"position" : 2,
"count" : 1
},
{
"_id" : ObjectId("5d387ecfbb676b173aa57fe4"),
"img" : "some url",
"name" : "The Three",
"__v" : 0,
"amount" : 17,
"available" : 16,
"collec" : ObjectId("5d36c0c34c86991db93bd7c8"),
"gen" : 3,
"metadata" : {},
"position" : 3,
"count" : 0
},
{
"_id" : ObjectId("5d387ecfbb676b173aa57fe4"),
"img" : "Some url",
"name" : "La 5",
"__v" : 0,
"amount" : 17,
"available" : 16,
"collec" : ObjectId("5d36c0c34c86991db93bd7c8"),
"gen" : 3,
"metadata" : {},
"position" : 4,
"count" : 12
}

I tried several things using aggregate and lookup but I can´t get make it work. 我尝试了一些使用聚合和查找的方法,但是无法使其正常工作。

The only I could get, was retrieve the info from AppUser and the total count.. 我唯一能得到的是从AppUser和总计数中检索信息。

Something like this (with mongoose): 像这样(猫鼬):

AppUser.aggregate([
    { $match: matchQuery },
    {$unwind: "$collectables"},

    {
        $lookup: 
        {
            from: "collectables",
            localField: "collectables.collectable",
            foreignField: "_id",
            as: "result"
        }
    },
    { $sort: { "result.position": 1 } },
    {$unwind: "$result"},
    { $addFields : { "result.count" : "$collectables.count" } 
},
    { $replaceRoot: { newRoot: "$result" } },
    { $skip: size * (page - 1) },
    { $limit: size }
 ]).exec((err, result) => 
{
    if (err) 
    {
        console.log(err);
        return res.status(401).send({ success: false });
    }
    else {
        return res.status(200).send({ success: true, result });
    }

});

So I need help because i have three days with this and I can´t get something nice... Thanks in advance... 所以我需要帮助,因为我花了三天时间才能得到很好的东西。

Below query will bring us the expected output 下面的查询将为我们带来预期的输出

db.appuser.aggregate([
  { $unwind: "$collectables" },
  {
    $lookup: {
      from: "collectables",
      localField: "collectables.collectable",
      foreignField: "_id",
      as: "result"
    }
  },
  {
    $project: { 
      result: 1,
      flag: { "$gt": [ {"$size": "$result"}, 0 ] },
      "collectables.count": 1,
      alias: 1,
      _id: 0
    }
  },
  {
    $match: { flag: true }
  }
]);

Unwind the appuser.collectables array, then do a lookup between the collections collectables and appuser , then use $project and $match to get the desired result. 放松的appuser.collectables数组,然后做集合之间的查找collectablesappuser ,然后使用$项目和$匹配以获得期望的结果。

In the $project stage added a flag to filter out the desired documents, by checking the size of the result array of the $lookup output. 在$ project阶段,通过检查$ lookup输出的结果数组的大小,添加了一个标记以过滤出所需的文档。

Sample Data used 使用的样本数据

db.collectables.find()


{
  "_id": "5d387ecfbb676b173aa57fe3",
  "img": "some url",
  "name": "La 5",
  "__v": 0,
  "amount": 17,
  "available": 16,
  "collec": "5d36c0c34c86991db93bd7c8",
  "gen": 3,
  "metadata": {

  },
  "position": 1
}

db.appuser.find()

[{
  "_id": "5d36dc9445526a215c4eff52",
  "twitter": "1",
  "alias": "ViktorCrowley",
  "__v": 25,
  "collectables": [
    {
      "count": 12,
      "collectable": "5d36c1ba4c86991db93bd7e7"
    },
    {
      "count": 25,
      "collectable": "5d36c13d4c86991db93bd7c9"
    },
    {
      "count": 8,
      "collectable": "5d381e122f25221126a98f9c"
    }
  ]
},
{
  "_id": "5d36dc9445526a215c4efga1",
  "twitter": "1",
  "alias": "John",
  "__v": 11,
  "collectables": [
    {
      "count": 10,
      "collectable": "5d387ecfbb676b173aa57fe3"
    }
  ]
},
{
  "_id": "6dc2dc9445526a215c4efga1",
  "twitter": "1",
  "alias": "Alice",
  "__v": 11,
  "collectables": [
    {
      "count": 25,
      "collectable": "5d387ecfbb676b173aa57fe3"
    },
    {
      "count": 3,
      "collectable": "5d36c13d4c86991db9312349"
    },
    {
      "count": 5,
      "collectable": "5d381e122f25221126a9711c"
    }
  ]
}]

Final Output 最终输出

{
  "alias": "John",
  "collectables": {
    "count": 10
  },
  "result": [
    {
      "_id": "5d387ecfbb676b173aa57fe3",
      "img": "some url",
      "name": "La 5",
      "__v": 0,
      "amount": 17,
      "available": 16,
      "collec": "5d36c0c34c86991db93bd7c8",
      "gen": 3,
      "metadata": {

      },
      "position": 1
    }
  ],
  "flag": true
}
{
  "alias": "Alice",
  "collectables": {
    "count": 25
  },
  "result": [
    {
      "_id": "5d387ecfbb676b173aa57fe3",
      "img": "some url",
      "name": "La 5",
      "__v": 0,
      "amount": 17,
      "available": 16,
      "collec": "5d36c0c34c86991db93bd7c8",
      "gen": 3,
      "metadata": {

      },
      "position": 1
    }
  ],
  "flag": true
}

Hope it helps! 希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM