我正在尝试根据相关字段加入以下两个文档,即users._id
和addressschemas.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']
}
}
}
}
}
])
但上述查询的结果是空的,有人能告诉我它的问题吗?
答案 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"
}
}
由于$lookup
与users
文档的原始字段一起创建了新字段,因此您在此新{{1}下的数组中的值为addressschemas
} field,因此我使用address
操作来摆脱这个数组。没有简单的方法将它们向上移动到一个级别,因为它在您想要的结果中,我认为最好像这样表示地址数据。
显然我假设用户文档只包含一个单一地址,如果不是这样,$undwind
操作将产生多个上述对象,每个对象包含一个不同的$unwind
字段,但是根据你想要的结果,我推断你在这两个文件之间有一对一的关系。