我将以下代码与$ lookup函数一起使用。
postSchemaModel.aggregate([{
"$geoNear": {
"near": { "type": "Point", "coordinates": [6.7336665, 79.8994071], "Typology": "post" },
"distanceField": "dist.calculated",
"maxDistance": 5000,
"includeLocs": "dist.location",
"spherical": true
}
},
{ "$limit": limit },
{ "$skip": startIndex },
{ "$sort": { "createdAt": -1 } },
{
"$lookup": {
"from": userSchemaModel.collection.name,
"localField": "user_id",
"foreignField": "_id",
"as": "user_id"
}
},
{
"$project": {
"post_data": 1,
"likes": 1,
"commentsCount": 1,
"post_img": 1,
"isUserLiked": 1,
"usersLiked": 1,
'exp_date': 1,
"has_img": 1,
"user_id": "$user_id",
"typology": 1,
"geometry": 1,
"category": 1,
"created": 1,
"createdAt": 1,
"updatedAt": 1,
}
},
]).then(async function(posts) {
//some code here
});
问题是这给了我 user_id 的空数组。以下是我收到的一个输出。
{ _id: 5ee1f89732fd2c33bccfec55,
post_data: 'vvhhh',
likes: 1,
commentsCount: 0,
post_img: null,
isUserLiked: false,
usersLiked: [ 5edf43b93859680cf815e577 ],
exp_date: 2020-06-12T18:30:00.000Z,
has_img: false,
typology: 'chat',
geometry:
{ pintype: 'Point',
_id: 5ee1f89732fd2c33bccfec56,
coordinates: [Array] },
category: [],
created: 1591867543468,
createdAt: 2020-06-11T09:25:43.478Z,
updatedAt: 2020-06-15T10:01:01.133Z,
user_id: [] }
在我的情况下,我不希望它为null,并且希望得到如下所示的输出。
{ _id: 5ee1f89732fd2c33bccfec55,
post_data: 'vvhhh',
likes: 1,
commentsCount: 0,
post_img: null,
isUserLiked: false,
usersLiked: [ 5edf43b93859680cf815e577 ],
exp_date: 2020-06-12T18:30:00.000Z,
has_img: false,
typology: 'chat',
geometry:
{ pintype: 'Point',
_id: 5ee1f89732fd2c33bccfec56,
coordinates: [Array] },
category: [],
created: 1591867543468,
createdAt: 2020-06-11T09:25:43.478Z,
updatedAt: 2020-06-15T10:01:01.133Z,
user_id: { img: 'default-user-profile-image.png',
_id: 5edd103214ce223088a59236,
user_name: 'Puka' }
}
我的userSchema如下所示
var userSchema = mongoose.Schema({
//some other fields
user_name: {
type: String,
max: 30,
min: 5
},
img: {
type: String,
default: 'default-user-profile-image.png'
},
//some other fields
});
userSchema.plugin(uniqueValidator);
var userSchemaModel = mongoose.model('users', userSchema);
module.exports = {
userSchemaModel,
}
根据这里的其他答案,我尝试使用 mongoose.Types.ObjectId(userId) ,但它给出了完整的空集。
这可能是问题所在,如果有人在几天之内坚持不懈,可以帮助我,这将非常有帮助。
更新: 发布架构
var postSchema = mongoose.Schema({
user_id: {
type: String,
required: true,
ref: 'users'
},
//other fields
var postSchemaModel = mongoose.model('posts', postSchema);
module.exports = {
postSchemaModel,
}
答案 0 :(得分:1)
由于user._id
(ObjectId
)和post.user_id
(String
)的数据类型不同,因此无法使用$lookup
联接这些字段。在执行$lookup
如果允许您更改架构,建议对ObjectId
使用post.user_id
var postSchema = mongoose.Schema({
user_id: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'users'
},
// ...other fields
但是请记住也将现有数据类型更改为ObjectId
。
如果出于某些原因真的不允许更改架构和现有数据。如果数据包含ObjectId
的有效十六进制表示形式(可从MongoDB v4.0获得),则可以将post.user_id转换为ObjectId
[
// prior pipeline stages
{ "$sort": { "createdAt": -1 } },
{
"$addFields": {
"user_id": { "$toObjectId": "$user_id" }
}
},
{
"$lookup": {
"from": userSchemaModel.collection.name,
"localField": "user_id",
"foreignField": "_id",
"as": "user_id"
}
},
// other stages
答案 1 :(得分:-1)
由于mongodb中的_id
字段存储为类型ObjectId
,但是在posts
集合中user_id
存储为类型string
,因此不是能够找到用户信息并带来空白数组。
要解决此问题,请在创建用户时在_id
集合中保存user
的纯字符串版本。例如
{
_id: ObjectId("5ee1f89732fd2c33bccfec55"),
doc_id: "5ee1f89732fd2c33bccfec55",
//other user info
}
,然后在$ lookup中使用此doc_id
字段
{
"$lookup": {
"from": userSchemaModel.collection.name,
"localField": "user_id",
"foreignField": "doc_id",
"as": "user_id"
}
}
通过这种方式,user_id
和doc_id
都将属于string
类型,并且不需要任何类型转换麻烦。