Nodejs mongoose数组嵌套如何操作

Nodejs mongoose数组嵌套如何操作

先说问题: 有很多情况下需要数组内在嵌套一个数组,比如: 一个用户下面有一个字段 // 书籍标签 tags: [{ name: String, memo: String, bookids: [{ type: mongoose.Schema.Types.ObjectId, ref: ‘book’ } ] } ] 表示一个用户有很多的标签,每个标签下边有很多他收藏的书籍信息 我想在插入标签并插入书籍信息 如下: // 设置书籍的标签信息 User.prototype.setUserBookTags = function(userid, bookid, tags, callback) { // 拆分标签字符串并重组 var tags_ = []; var arr = tags.split(’,’); for (var i = 0; i < arr.length; i++) { tags_.push({ name: arr[i], bookids: [bookid] }); } // 更新标签信息 UserModel.update({ id: userid }, { $pushAll: { tags: tags } }, { safe: true, multi: true }, function(err, user_) { if (err) return callback(err); if (user_) return callback(err, user_); }); } 这个是成功的,新建了一个书籍标签并且将书籍id插入到了标签数组内 问题来了: 怎么将书籍id从书籍标签中移除呢? 求大家给个方法或者思路


6 回复

Node.js Mongoose 数组嵌套操作

问题描述

在处理复杂数据结构时,我们经常遇到需要在一个数组内嵌套另一个数组的情况。例如,一个用户对象可能包含多个标签(tags),每个标签下又有多个书籍ID(bookids)。现在的问题是如何在插入和删除这些嵌套数组中的元素。

示例模型定义

首先,我们需要定义一个简单的Mongoose模型来展示这个问题:

const mongoose = require('mongoose');

const bookSchema = new mongoose.Schema({
    name: String,
    memo: String
});

const tagSchema = new mongoose.Schema({
    name: String,
    memo: String,
    bookids: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Book' }]
});

const userSchema = new mongoose.Schema({
    username: String,
    tags: [tagSchema]
});

const User = mongoose.model('User', userSchema);
const Book = mongoose.model('Book', bookSchema);

module.exports = { User, Book };

插入书籍标签及书籍ID

假设我们要向一个用户的某个标签中添加书籍ID。我们可以使用 $push 操作符来实现这一点:

const addUserBookTag = async (userid, bookid, tagname, tagmemo) => {
    const user = await User.findById(userid);
    
    // 查找或创建标签
    let tag = user.tags.find(t => t.name === tagname && t.memo === tagmemo);
    if (!tag) {
        tag = {
            name: tagname,
            memo: tagmemo,
            bookids: []
        };
        user.tags.push(tag);
    }

    // 添加书籍ID到标签的bookids数组中
    tag.bookids.push(bookid);

    await user.save();
};

删除书籍ID

如果我们要从某个标签的 bookids 数组中移除书籍ID,可以使用 $pull 操作符:

const removeBookFromTag = async (userid, bookid, tagname, tagmemo) => {
    const user = await User.findById(userid);
    
    // 查找标签
    let tag = user.tags.find(t => t.name === tagname && t.memo === tagmemo);
    if (tag) {
        // 从标签的bookids数组中移除书籍ID
        tag.bookids.pull(bookid);
        await user.save();
    }
};

总结

通过上述示例代码,我们展示了如何在嵌套数组中插入和删除数据。使用Mongoose的 $push$pull 操作符可以方便地管理嵌套数组的数据。希望这些示例能够帮助你更好地理解和处理Node.js中Mongoose的数组嵌套操作。


我的思路: find --> modify --> save(update)

已经这么做了,但是感觉不太好,希望能从语法或者api下手 mongodb好像没有提供深层数组修改的语法,查询的倒是有

用pull

怎么pull? 这样:pull : {‘tags.bookids’ : bookid} ?

要解决这个问题,你需要使用Mongoose提供的更新操作符 $pull 来从嵌套数组中移除书籍ID。以下是如何实现这一功能的步骤及示例代码。

步骤说明

  1. 定义模型:确保你的Mongoose模型定义了如下的结构。
  2. 移除书籍ID:使用 $pull 操作符来移除特定书籍ID。

示例代码

首先,假设你已经有定义好的 UserModelBookModel。这里是一个示例函数,用来从用户的标签中的书籍ID数组中移除指定的书籍ID:

User.prototype.removeBookFromTag = function (userid, bookid, tagname, callback) {
    // 使用 $pull 操作符从嵌套的 bookids 数组中移除特定的 bookid
    UserModel.update(
        { _id: userid, 'tags.name': tagname }, // 确保匹配正确的用户以及标签名
        { $pull: { 'tags.$.bookids': bookid } }, // 从指定标签下的 bookids 中移除书本
        { safe: true },
        function (err, numAffected) {
            if (err) return callback(err);
            if (numAffected === 0) {
                return callback(new Error("No document matched the criteria"));
            }
            callback(null, "Book removed from tag successfully");
        }
    );
};

解释

  • update 方法:用于更新匹配文档的字段。这里的查询条件包括用户ID和标签名,以确保我们修改的是正确的目标。
  • $pull 操作符:用于从数组中删除匹配的元素。'tags.$.bookids' 中的 $ 是一个占位符,用于引用符合条件的数组元素。
  • 错误处理:如果更新失败,则返回错误;如果没有任何文档被更新(即没有找到匹配项),则返回相应的错误信息。

这样,你就可以从嵌套数组中移除特定的书籍ID了。希望这能帮助你解决问题!

回到顶部