【问题标题】:Mongoose update using dot notation and $ operatorMongoose 使用点符号和 $ 运算符更新
【发布时间】:2022-01-24 22:16:26
【问题描述】:

我有一个我想使用 findOneAndUpdate 更新的对象,但它似乎不起作用.. 我已经尝试使用 $ 运算符,但它不起作用,但是一旦我删除 $ 运算符,调用就会显示错误。

MongoServerError: Cannot create field 'categoryfilter' in element {store: [ { productname: "monitor", price: 1500, quantity: 5, categoryfilter: "Monitors", description: "tests", timestamp: "December 24th 2021, 1:39:36 pm", _id: ObjectId('61c55d687d8ff305de3ed044'), 0: { categoryfilter: "Monitors", description: "testsss", price: 1500, productname: "monitor", quantity: 5, timestamp: "December 24th 2021, 1:39:36 pm" } } ]}    at MessageStream.messageHandler (C:\Users\gamex\Desktop\my files\goldenwell\server\node_modules\mongodb\lib\cmap\connection.js:467:30)   
    at MessageStream.emit (events.js:376:20)   
    at processIncomingData (C:\Users\gamex\Desktop\my files\goldenwell\server\node_modules\mongodb\lib\cmap\message_stream.js:108:16)        
    at MessageStream._write (C:\Users\gamex\Desktop\my files\goldenwell\server\node_modules\mongodb\lib\cmap\message_stream.js:28:9)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at MessageStream.Writable.write (internal/streams/writable.js:303:10)
    at TLSSocket.ondata (internal/streams/readable.js:745:22)
    at TLSSocket.emit (events.js:376:20)       
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9) {
  operationTime: new Timestamp({ t: 1640325515, i: 17 }),
  ok: 0,
  code: 28,
  codeName: 'PathNotViable',
  '$clusterTime': {
    clusterTime: new Timestamp({ t: 1640325515, i: 17 }),
    signature: {
      hash: new Binary(Buffer.from("c08511e0a3727ac6636aa2c56b4587cfcf0c2396", "hex"), 0),    
      keyId: new Long("7013342858887299079")   
    }
  }
}

这是我使用 mongoose 创建的架构。

import mongoose from 'mongoose';

const OwnerSchema = mongoose.Schema({
    username: {
        require: true,
        type: String,
    },
    password: {
        require: true,
        type: String,
    },
    isAdmin: {
      type: Boolean,
      default: true,
    },
    store: [
        {
            productname: {
                type: String,
                required: true,
              },
            price: {
                type: Number,
                required: true,
              },
            quantity: {
                type: Number,
                required: true,
              },
            categoryfilter: {
              type: String,
              required: true
            },
            description: {
                type: String,
                required: true,
              },
            imageBase64: {
                type: String,
                required: true,
              },
            timestamp: {
              type: String,
              required: true,
            }
            
        }
    ]
});

const OwnerModels = mongoose.model('OwnerModels', OwnerSchema);

export default OwnerModels;

这是我的更新查询。我尝试使用 $ 运算符,但它似乎根本没有用,所以删除它。

export const updateProduct = async (req,res) => {

    const { id } = req.params;

    try {
        if(!mongoose.Types.ObjectId.isValid(id)) return res.status(404).json({ message: 'Invalid ID' });

        await OwnerModels.findOneAndUpdate({'_id': id, store:{ $elemMatch: { productname: req.body.store[0].productname }}},
            {$set: 
                {
                    "store.productname": req.body.store[0].productname,
                    "store.price": req.body.store[0].price,
                    "store.quantity": req.body.store[0].quantity,
                    "store.categoryfilter": req.body.store[0].categoryfilter,
                    "store.description": req.body.store[0].description,
                    "store.timestamp": req.body.store[0].timestamp 
                }
            }, 
            {new: true, safe: true, upsert: true}, (error, response) => {
                if(error){
                    console.log(error)
                }else{
                    console.log(response)
                }
            }
            );

    } catch (error) {
        res.status(404).json(error)
    }

}

【问题讨论】:

  • 您能发布您的OwnerModels 架构吗?
  • 请检查我的架构...我更新了帖子
  • 这能回答你的问题吗? Mongoose delete other objects after update
  • 它不起作用..也许我会尝试删除 $elemMatch 并使用 arrayFilter。

标签: node.js mongoose


【解决方案1】:

因为store 是一个数组,mongodb 无法通过{ $set: { 'store.categoryfilter': ... } } 语句知道要更新store 中的哪个元素。

$elemMatch 查询仅用于文档级别的查询过滤器,它不会选择特定的store 元素进行更新。

正确的选择是在更新语句中使用arrayFilter

【讨论】:

  • 也许我会尝试删除 $elemMatch 并使用 arrayFilter。我对 mongo 查询有点陌生,这是我第一次尝试在我的数组存储中编辑特定对象。
【解决方案2】:

尝试使用findByid 检索OwnerModel,然后使用push 方法更新store 数组。
您需要使用save 方法保存更新的对象。

const owner = await OwnerModels.findByid(id);
if (!owner) {
    return res.status(404).json({ message: "Owner not found" });
}
owner.store.push(req.body.store);
await owner.save();

res.status(200).json({ message: "Updated" })

最后,您可能需要在 imageBase64 字段中添加一个 default 值,因为我没有在您的正文参数中看到它:

imageBase64: {
    type: String,
    required: true,
    default: ""
},

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-11
    • 2015-10-16
    • 1970-01-01
    • 2012-05-21
    • 2020-03-31
    • 1970-01-01
    • 2012-05-08
    • 2015-10-22
    相关资源
    最近更新 更多