使用自定义UID设置mongo的_id

时间:2015-07-01 23:01:21

标签: javascript node.js mongodb mongoose database

背景

我无法控制来自我的数据库文档 Things 帖子后事件。当帖子出现时,我已经编写了一个名为findOrCreate()的函数(它将在Things文档中找到或创建一个记录(对象?))。为了减少冗余,我想使用第三方POST有效负载字段nuid来替换该记录(对象)的默认_id

问题:

  

如何正确地将_id替换为名为nuid的有效负载字段?

示例有效负载:

curl -H "Content-Type: application/json" -X POST -d '{"participant":{"nuid":"98ASDF988SDF89SDF89989SDF9898"}}' http://localhost:9000/api/things

模式

'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var ThingSchema = new Schema(
  {nuid: String}
);

module.exports = mongoose.model('Thing', ThingSchema);

thing.controller.js

//*currently this function will have both _id and a nuid (which works but not desirable)
exports.findOrCreate = function(req, res) {

  var query = {"nuid": req.body.participant.nuid};
  var update = {nuid: req.body.participant.nuid};

  Thing.findOneAndUpdate(
      query,
      update,
      {upsert: true},
      function(err, thing){
        console.log(thing, "thing");
        console.log(err, "err");
        if(!thing) {
          Thing.create(req.body.participant, function(err, thing) {
            if(err) { return handleError(res, err); }
          });
        };
        if(err){return handleError(res, err); }
      }
  );
});

事/ index.js

var express = require('express');
var controller = require('./thing.controller');

var router = express.Router();

router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.findOrCreate);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);

module.exports = router;

我找到了一个参考资料,但我仍然不了解如何正确使用它,因为模型发生在有效负载之前Stack Reference

1 个答案:

答案 0 :(得分:1)

您可以将_id的值设置为您想要的任何值,并使用" upsert"同样。这只是在更新声明中使用$setOnInsert的问题:

var thingSchema = new Schema({
  "_id": String
},{ "_id": false });

var Thing = mongoose.model('Thing',thingSchema);


Thing.findByIdAndUpdate("98ASDF988SDF89SDF89989SDF9898",
  { "$setOnInsert": { "_id": "98ASDF988SDF89SDF89989SDF9898" } },
  { "upsert": true },
  function(err,doc) {
    if (err) throw err;
    console.log(doc);
  }
)

如果_id不存在,则会创建一个新文档,或者在匹配的文档中应用更新(在示例中没有任何内容会更新,只是匹配并返回)。

如果您要更新任何其他数据,请使用$set或其他运算符为_id以外的其他字段添加。

作为从客户端API(或作为安全性)生成UUID的替代方法,您可以使用类似node-uuid的内容并将生成插入到模式中:

var thingSchema = new Schema({
  "_id": { "type": String, default: function genUUID() { uuid.v1() } }
},{ "_id": false });

var Thing = mongoose.model('Thing',thingSchema);


Thing.findOneAndUpdate(
  { "uname": "sam" },
  { "$set": { "uname": "sam" } },
  { "upsert": true },
  function(err,doc) {
    if (err) throw err;
    console.log(doc);
  }
)

这样即使没有为操作提供_id,也会创建一些东西。这里有一些简单的例子,但它确定了设置默认值。