用自定义的UID设置mongo的_id

背景:

我无法控制来自我的数据库文档“ 事情”的事件 。 当post进来时,我写了一个名为findOrCreate()的函数(它会在Things文档中find或创build一个logging(object?))。 为了减less冗余,我想使用第三方POST负载字段nuid来replace该logging(对象)的默认_id

题:

我如何正确地replace_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; 

我find了一个引用,但我仍然不明白如何正确使用它,因为模型发生在有效载荷堆栈引用之前

您可以将_id的值设置为任何您想要的值,并使用“upsert”来完成。 这只是在update语句中使用$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不存在,或者应用更新(在该示例中没有更新,只是匹配并返回)到匹配的文档,则会创build一个新文档。

如果您想要更新的任何其他数据使用$set或其他运算符作为要更改的字段,而不是_id


作为从客户端API(或作为安全)生成UUID的替代scheme,您可以使用类似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 ,也会创build一些东西。 这里是一个简单的例子,但它使得设置一个默认的点。