You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express中Mongoose查询Tweet时populate likes返回空数组问题

问题:查询Tweet时populate likes字段返回空数组

问题详情

我定义了如下两个Mongoose Schema:

Like模型Schema

//create likes schema
const likes = mongoose.Schema({
    liked: {
        type: Boolean,
        default: false
    },
    tweet: {
        type: Schema.Types.ObjectId,
        ref: "Tweet"
    },
    author: {
        type: Schema.Types.ObjectId,
        ref: "User"
    }
});

module.exports = mongoose.model('Like', likes);

Tweet模型Schema

const tweets = mongoose.Schema({
    content: {
        type: String,
        required: true,
    },
    author: {
        type: Schema.Types.ObjectId,
        ref: "User"
    },
    likes: [{
            type: Schema.Types.ObjectId,
            ref: "Like"
        }]
});

module.exports = mongoose.model('Tweet', tweets);

测试Like的populate查询时结果正常:

const likes = await Like.find().populate("author", "_id name email").populate("tweet", "_id content").exec()
res.json(likes)

返回数据:

[
    {
        "_id": "63921e53deb31c60249901e4",
        "liked": true,
        "tweet": {
            "_id": "63921e50deb31c60249901e1",
            "content": "tweet 1"
        },
        "author": {
            "_id": "63921e2ddeb31c60249901dd",
            "name": "Dave",
            "email": "something@gmail.com"
        },
        "createdAt": "2022-12-08T17:26:43.650Z",
        "updatedAt": "2022-12-08T17:26:43.650Z",
        "__v": 0
    }
]

但查询Tweet并populate likes字段时,得到的likes数组为空:

const tweets = await Tweet.find()
    .populate("author", "_id name email")
    .populate("likes", "_id")
    .sort({updatedAt: "desc"})
    .exec()

res.status(200).json(tweets)

返回数据:

[
    {
        "_id": "6393701aa62997f3454e81e1",
        "content": "My tweet",
        "author": "63936ffaa62997f3454e81dd",
        "likes": [],
        "createdAt": "2022-12-09T17:27:54.146Z",
        "updatedAt": "2022-12-09T17:27:54.146Z",
        "__v": 0
    }
]

实际Like集合中存在对应该Tweet的记录:

[
    {
        "_id": "63937140df6222756bd84ede",
        "liked": true,
        "tweet": {
            "_id": "6393701aa62997f3454e81e1",
            "content": "My tweet"
        },
        "author": {
            "_id": "63936ffaa62997f3454e81dd",
            "name": "Dave",
            "email": "admin@gmail.com"
        },
        "createdAt": "2022-12-09T17:32:48.251Z",
        "updatedAt": "2022-12-09T17:32:48.251Z",
        "__v": 0
    }
]

解决方案

问题核心是双向引用未同步更新:Mongoose不会自动维护跨文档的双向关联,你创建Like记录时仅在Like文档中关联了Tweet ID,但未将Like ID同步添加到对应Tweet的likes数组中,导致populate时无法匹配到关联数据。

修复步骤:

  1. 创建Like时同步更新Tweet
    新增Like记录后,手动更新对应Tweet的likes数组:

    // 创建Like示例
    const newLike = new Like({
        liked: true,
        tweet: tweetId, // 目标Tweet的ID
        author: userId
    });
    
    await newLike.save();
    
    // 同步更新Tweet的likes数组
    await Tweet.findByIdAndUpdate(
        tweetId,
        { $push: { likes: newLike._id } },
        { new: true } // 返回更新后的文档
    );
    
  2. 补全已有数据的关联
    针对已存在的Like记录,批量同步到对应Tweet:

    const allLikes = await Like.find().populate('tweet');
    
    for (const like of allLikes) {
        if (like.tweet && !like.tweet.likes.includes(like._id)) {
            await Tweet.findByIdAndUpdate(
                like.tweet._id,
                { $push: { likes: like._id } }
            );
        }
    }
    
  3. 可选:用中间件自动维护关联
    给Like模型添加post中间件,自动处理关联更新,避免手动操作:

    // 保存Like后同步更新Tweet
    likes.post('save', async function(doc) {
        await Tweet.findByIdAndUpdate(
            doc.tweet,
            { $addToSet: { likes: doc._id } }, // $addToSet避免重复添加
            { new: true }
        );
    });
    
    // 删除Like时从Tweet中移除关联
    likes.post('remove', async function(doc) {
        await Tweet.findByIdAndUpdate(
            doc.tweet,
            { $pull: { likes: doc._id } },
            { new: true }
        );
    });
    

完成以上操作后,重新执行Tweet的populate查询,即可正确获取到关联的Like记录。

内容的提问来源于stack exchange,提问作者WaqasRaza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:55:09