MongoDB

时间:2017-04-24 05:13:18

标签: mongodb

我正在尝试根据相关字段加入以下两个文档,即users._idaddressschemas.userId

示例users文档;

{
    "_id" : ObjectId("58f74901b3ec8e2d0bc898d5"),
    "fullName" : "public user",
    "firstName" : "public",
    "lastName" : "user",
    "email" : "user@gmail.com",
    "password" : "$2a$10$thYCJS62ejUxxzIlpIfiXeRxswQPzU4sVhc4PeoGxAXN3/IBxnxeO",
    "mobile" : "9876543210",
    "countryCode" : "+91",
    "accountEnabled" : true,
    "__v" : 0
}

示例addressschemas文档;

{
    "_id" : ObjectId("58f9b18880a35c281078f42b"),
    "userId" :  ObjectId("58f74901b3ec8e2d0bc898d5"),
    "deliveryName" : "test",
    "deliveryAddress" : "new address",
    "deliveryState" : "Haryana",
    "deliveryCity" : "Gurgaon",
    "deliveryZipCode" : "122001",
    "deliveryCountryCode" : "+91",
    "deliveryMobile" : "9876543211",
    "deliveryEmail" : "subadmin2@email.com",
    "__v" : 0
}

前面提到的连接所需的结果应该是以下内容;

{

    "_id" : ObjectId("58f74901b3ec8e2d0bc898d5"),
    "fullName" : "public user",
    "firstName" : "public",
    "lastName" : "user",
    "email" : "user@gmail.com",
    "password" : "$2a$10$thYCJS62ejUxxzIlpIfiXeRxswQPzU4sVhc4PeoGxAXN3/IBxnxeO",
    "mobile" : "9876543210",
    "countryCode" : "+91",
    "accountEnabled" : true,

    "userId" :ObjectId("58f74901b3ec8e2d0bc898d5"),
    "deliveryName" : "test",
    "deliveryAddress" : "new address",
    "deliveryState" : "Haryana",
    "deliveryCity" : "Gurgaon",
    "deliveryZipCode" : "122001",
    "deliveryCountryCode" : "+91",
    "deliveryMobile" : "9876543211",
    "deliveryEmail" : "subadmin2@email.com"
}

我用来实现此目的的查询;

db.getCollection('users').aggregate([
  {
    $match: {
      _id: ObjectId("58f74901b3ec8e2d0bc898d5")
    }
  },
  {
    $lookup: {
      from: "addressschemas",
      localField: "_id",
      foreignField: "usersId",
      as: "results"
    }
  },
  {
    $project: {
      addressschemas: {
        $filter: {
          input: "$_id",
          cond: {
            $eq: ['$$addressschemas.userId', '$users._id']
          }
        }
      }
    }
  }
])

但上述查询的结果是空的,有人能告诉我它的问题吗?

2 个答案:

答案 0 :(得分:2)

MongoDB以两种方式定义关系

(1)参考文献 (2)嵌入式文件

在实体之间存在多对多关系的应用中,引用是优选的。

嵌入式文档在实体之间存在一对多关系的应用程序中更为可取。

在上面提到的场景中,似乎用户和地址统一之间存在一对多的关系。

因此,可以将相应用户的地址定义为用户文档中的嵌入文档,从而便于在单次访问数据库服务器时检索用户文档。

E.g

{
    "_id": ObjectId("58f74901b3ec8e2d0bc898d5"),
    "fullName": "public user",
    "firstName": "public",
    "lastName": "user",
    "email": "user@gmail.com",
    "password": "$2a$10$thYCJS62ejUxxzIlpIfiXeRxswQPzU4sVhc4PeoGxAXN3/IBxnxeO",
    "mobile": "9876543210",
    "countryCode": "+91",
    "accountEnabled": true,
    "__v": 0,
    "addressschemas": [
        {
            "deliveryName": "test",
            "deliveryAddress": "new address",
            "deliveryState": "Haryana",
            "deliveryCity": "Gurgaon",
            "deliveryZipCode": "122001",
            "deliveryCountryCode": "+91",
            "deliveryMobile": "9876543211",
            "deliveryEmail": "subadmin2@email.com"
        }
    ]
}

答案 1 :(得分:1)

您可以使用以下查询获得近似结果;

db.getCollection('users').aggregate([
  {
    $match: {
      _id: ObjectId("58f74901b3ec8e2d0bc898d5")
    }
  },
  {
    $lookup: {
      from: "addressschemas",
      localField: "_id",
      foreignField: "userId",
      as: "address"
    }
  },
  {
    $unwind : "$address" 
  },
  {
    $project: {
      __v: 0,
      "address.__v": 0,
      "address._id": 0,
      "address.userId": 0
    }
  }
])

使用您的测试数据将生成以下文档;

{
  "_id": ObjectId("58f74901b3ec8e2d0bc898d5")
  "fullName": "public user",
  "firstName": "public",
  "lastName": "user",
  "email": "user@gmail.com",
  "password": "$2a$10$thYCJS62ejUxxzIlpIfiXeRxswQPzU4sVhc4PeoGxAXN3/IBxnxeO",
  "mobile": "9876543210",
  "countryCode": "+91",
  "accountEnabled": true,
  "address": {
    "deliveryName": "test",
    "deliveryAddress": "new address",
    "deliveryState": "Haryana",
    "deliveryCity": "Gurgaon",
    "deliveryZipCode": "122001",
    "deliveryCountryCode": "+91",
    "deliveryMobile": "9876543211",
    "deliveryEmail": "subadmin2@email.com"
  }
}

由于$lookupusers文档的原始字段一起创建了新字段,因此您在此新{{1}下的数组中的值为addressschemas } field,因此我使用address操作来摆脱这个数组。没有简单的方法将它们向上移动到一个级别,因为它在您想要的结果中,我认为最好像这样表示地址数据。

显然我假设用户文档只包含一个单一地址,如果不是这样,$undwind操作将产生多个上述对象,每个对象包含一个不同的$unwind字段,但是根据你想要的结果,我推断你在这两个文件之间有一对一的关系。