使用 mongo 中的 $inc 字段进行更新会出错

Posted

技术标签:

【中文标题】使用 mongo 中的 $inc 字段进行更新会出错【英文标题】:Updating using $inc field in the mongo gives error 【发布时间】:2020-07-19 03:53:22 【问题描述】:

所以我试图更新我的数据库中的一个字段以每次都增加它。像一个计数器,以便我不断获得更新的值。为此,我正在使用这个

var CounterSchema = new Schema(
  _id: String,
  _const: String,
  count: Number
);

然后我将模型创建为

const Counter = mongoose.model("counter", CounterSchema);

然后我正在使用一个函数来更新我的集合中的一个字段,例如以下......

async function getNextSequence() 
 

  var count = await Counter.findOneAndUpdate(
     _const: "some" ,

     $inc:  count: 1  ,
     new: true 
  );

  
  return count.count;

但是在运行上述函数时会出现一些错误。我已经确定给定的 _id 存在,这是我得到的错误……

(node:10788) DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify` option set to false are deprecated. See: https://mongoosejs.com/docs/deprecations.html#findandmodify

9:58 PM

 ValidationError: Url validation failed: counter: Cast to Number failed for value "Promise  <pending> " at path "counter"

9:58 PM

at ValidationError.inspect (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/error/validation.js:61:24)

9:58 PM

at formatValue (internal/util/inspect.js:493:31)

9:58 PM

at inspect (internal/util/inspect.js:191:10)

9:58 PM

at Object.formatWithOptions (util.js:84:12)

9:58 PM

at Console.(anonymous function) (console.js:191:15)

9:58 PM

at Console.log (console.js:202:31)

9:58 PM

Jump Toat /app/server.js:107:39

9:58 PM

at /rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/helpers/promiseOrCallback.js:16:11

9:58 PM

at /rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:4860:21

9:58 PM

at _done (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:3120:16)

9:58 PM

at fn (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:3135:18)

9:58 PM

at callbackWrapper (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:3089:20)

9:58 PM

at /rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:4837:16

9:58 PM

at /rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/helpers/promiseOrCallback.js:16:11

9:58 PM

at /rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:4860:21

9:58 PM

at $__save.error (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/model.js:489:16)

9:58 PM

errors:

9:58 PM

 counter:

9:58 PM

 CastError: Cast to Number failed for value "Promise  <pending> " at path "counter"

9:58 PM

at new CastError (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/error/cast.js:29:11)

9:58 PM

at model.$set (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/document.js:1233:9)

9:58 PM

at model._handleIndex (/rbd/pnpm-volume/f971d4d8-b5ba-4fbb-87f2-7580f1e7da53/node_modules/.registry.npmjs.org/mongoose/5.9.7/node_modules/mongoose/lib/document.js:972:14)

9:58 PM

我有一个 post api 来更新计数器。我制作了两种模式,一种用于跟踪更新,另一种用于推送真正的更新计数……无论如何,我只是在尝试新的东西。!!

app.post("/api/shorturl/new", function(req, res) 
  var url = req.body.url;
  url = url.replace(/^https?:\/\//, "");
  console.log("url string" + url);

  dns.lookup(url, async function(err, address, family) 
    if (err) 
      return console.log("error in url" + err);
     else 
      console.log("inside else lookup");

      UrlModel.find( url: url )
        .then(hello => 
          if (hello.length == 0) 
            console.log("url length is 0");
            console.log("url length is 0" + getNextSequence());

            UrlModel.create( url: url, counter: getNextSequence() , function(
              err,
              url
            ) 
              if (err) return console.log(err);
              else return res.json( success: url );
            );
           else 
            console.log("not 0");
            //           return the index of the sored file
          
        )
        .catch(message => 
          console.log("error message catch" + message);
        );

      
    
);

【问题讨论】:

【参考方案1】:

你写的函数的返回值是一个承诺,因为等待之后

return 行被执行并返回一个承诺。为了解决这个承诺,你还必须用 async 函数包装这个函数。

async function run() 
  const sequence = await getNextSequence();
  console.log(sequence);


run();

现在你会得到你想要的。

【讨论】:

【参考方案2】:

您已将 getNextSequence 定义为异步函数,因此它会自动将其包装到 Promise 中。尝试将其更改为:

UrlModel.create( url: url, counter: await getNextSequence() , ...

【讨论】:

我刚刚通过将所有内容嵌套在 thenables 中来解决。你的解决方案行不通。因为那时我的通话乐趣必须是异步的。总之谢谢。

以上是关于使用 mongo 中的 $inc 字段进行更新会出错的主要内容,如果未能解决你的问题,请参考以下文章

学习mongo系列修改器($inc/$set/$unset/$push/$pop/upsert)

如何使用 MongoRepository 接口更新 mongo db 中的特定字段?

如何使用 java 驱动程序更新 mongo db 中的文档字段?

Mongo更新数组内对象的多个字段

Spring Mongo 仅通过新 POJO 的非空字段进行更新

Mongo - 更新文档时使用另一个字段的结果更新一个字段