【问题标题】:MongooseError: Query was already executed: in pre hook ['updateOne', 'findOneAndUpdate', 'update', 'updateMany'] using this.set in itMongooseError:查询已执行:在 pre hook ['updateOne', 'findOneAndUpdate', 'update', 'updateMany'] 中使用 this.set
【发布时间】:2022-03-24 05:39:55
【问题描述】:

我在 v6.1.5 上使用猫鼬。

我正在尝试在更新函数上创建一个 mongoose 挂钩,以跟踪在更新期间更改的元素,并使其具有公共插件。

schema.pre(['updateOne', 'findOneAndUpdate', 'update', 'updateMany'], async function () {
    const updatedFields = this.getUpdate()

    if (isNull(updatedFields)) {
      return
    }

    const trackedFields = reduce(toPairs(updatedFields), (acc, [key, value]: [string, any]): any => {
      if (includes(fieldsToTrack, key)) {
        return [...acc, {
          field: `${key}`,
          changedTo: value,
          at: Date.now()
        }]
      }

      return acc
    }, [])

    const docUpdated = await this.model.findOne(this.getQuery())
    const oldTrackedFields = docUpdated.get(`${name}`)

    this.set({
      [name]: [...oldTrackedFields, ...trackedFields]
    }).catch((err) => console.log(err))
  })

在我的测试中运行代码时:,我在控制台中遇到一个奇怪的错误,它不会阻止逻辑,但会抛出这个:

it.only('should add modified field in __tokens if the field is tracked', async () => {
        const schema = new Schema({
          name: String,
          price: Number,
          toto: String
        })

        schema.plugin(mongooseTracker, {
          fieldsToTrack: ['name', 'toto'],
          name: '__tokens'
        })

        const Model = mongoose.model('test7', schema)

        await Model.create({ price: 10, name: 'nom', toto: 'c est moi' })
        await Model.findOneAndUpdate({ price: 10 }, { name: 'nouveauNom' })

        const doc = await Model.findOne({ price: 10 })

        expect(doc).toEqual(
          expect.objectContaining({
            '__tokens': expect.arrayContaining([
              expect.objectContaining({
                changedTo: 'nouveauNom',
                field: 'name'
              })
            ])
          })
        )
      })
console.log
    MongooseError: Query was already executed: test7.findOneAndUpdate({ price: 10 }, {
      '$set': {
        __to...
        at model.Query._wrappedThunk [as _findOneAndUpdate] (/home/barder/xxx/mongoose-tracker/node_modules/mongoose/lib/helpers/query/wrapThunk.js:21:19)
        at /home/barder/xxx/mongoose-tracker/node_modules/kareem/index.js:281:16
        at _next (/home/barder/xxx/mongoose-tracker/node_modules/kareem/index.js:103:16)
        at /home/barder/xxx/mongoose-tracker/node_modules/kareem/index.js:513:38
        at processTicksAndRejections (node:internal/process/task_queues:78:11) {
      originalStack: 'Error: \n' +
        '    at model.Query._wrappedThunk [as _findOneAndUpdate] (/home/barder/xxxx/mongoose-tracker/node_modules/mongoose/lib/helpers/query/wrapThunk.js:25:28)\n' +
        '    at /home/barder/xxx/mongoose-tracker/node_modules/kareem/index.js:281:16\n' +
        '    at _next (/home/barder/xxx/mongoose-tracker/node_modules/kareem/index.js:103:16)\n' +
        '    at /home/barder/xxx/mongoose-tracker/node_modules/kareem/index.js:513:38\n' +
        '    at processTicksAndRejections (node:internal/process/task_queues:78:11)'
    }

我正在窃听它并发现,似乎 this.set 是一个重复的查询,但我不明白为什么?这是因为更新函数使用 $set 所以它会重复调用吗?使用 .clone 是一个很好的解决方案吗?

请随时给我/我们反馈,我/我们将不胜感激。

【问题讨论】:

    标签: javascript typescript mongoose


    【解决方案1】:

    您不能在 mangoose 中运行两次查询,但可以克隆并运行它。尝试改变

    const doc = await Model.findOne({ price: 10 })
    

    const doc = await Model.findOne({ price: 10 }).clone()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多