Sto costruendo un servizio REST in stile CRUD con Node.js, Express e MongoDB utilizzando mangusta. Questo servizio consentirà agli utenti di un'applicazione Android già esistente di caricare/sincronizzare i contenuti dei loro singoli database online.Utilizzo di UUID in mangusta per i riferimenti all'ObjectID
Il modello dati per l'applicazione già esistente utilizza UUID (generati in Java) che si scontrano con i campi di stile _id
monotonici di MongoDB più brevi. Poiché il modello di dati esiste già e viene popolato con i dati di molti utenti, non riesco a convertire i dati di origine in stile monotonico MongoDB _id
s. Questo mi ha lasciato con 2 opzioni a cui posso pensare: 1) Crea Mongo/Mongoose (o qualche altro ODM) gioca bene con UUID completi invece del monotonico _id
s o 2) aggiungi un campo uuid al modello di mangusta in aggiunta al campo _id
e combattere le insidie di questo approccio. Sto tentando di scegliere l'opzione n. 1 e l'esecuzione di problemi con i riferimenti a ObjectID.
Originariamente mi sono imbattuto in mongoose-uuid, ma sfortunatamente questo non funziona correttamente per il mio caso d'uso perché sovrascriveva il mio valore esplicitamente impostato _id
durante la creazione di nuovi oggetti Mongoose. Immergendosi nel codice del plugin, si presuppone che un oggetto sia nuovo (chiamando il valore di .isNew
di Mongoose) e quindi sovrascrive lo _id
con un nuovo uuid. Poiché ho bisogno di mantenere l'uuid originale quando creo nuovi documenti in Mongo, questo plugin non funziona per me.
Successivamente, ho trovato un post di Aaron Heckmann, creatore di mangusta, su un argomento simile. Questo è stato utile, tuttavia ora sto riscontrando il problema in cui non riesco a far riferimento ai miei schemi di mangimi in base a ObjectID, dal momento che tecnicamente stanno facendo riferimento l'un l'altro usando String `_id.
schema esempio:
var mongoose = require('mongoose');
var uuid = require('node-uuid');
var Schema = mongoose.Schema;
var trackPassSchema = new Schema({
_id: { type: String, default: function genUUID() {
uuid.v1()
}},
//Omitting other fields in snippet for simplicity
vehicle: [
{type: Schema.Types.ObjectId, required: true, ref: 'Vehicle'}
]
});
module.exports = mongoose.model('TrackPass', trackPassSchema);
Riferimento schema:
var mongoose = require('mongoose');
var uuid = require('node-uuid');
var Schema = mongoose.Schema;
var vehicleSchema = new Schema({
_id: { type: String, default: function genUUID() {
uuid.v1()
}},
//Omitting other fields in snippet for simplicity
description: {type: String},
year: {type: Number}
});
module.exports = mongoose.model('Vehicle', vehicleSchema);
Quando tento di chiamare save()
un trackPass che è stata passata in dalla mia applicazione:
var trackPass = new TrackPass(req.body);
//Force the ID to match what was put into the request
trackPass._id = req.params.id;
trackPass.save(function (err) { ... }
ottengo il seguente errore:
{ [CastError: Cast to ObjectId failed for value "b205ac4d-fd96-4b1e-892a-d4fab818ea2a" at path "vehicle"]
message: 'Cast to ObjectId failed for value "b205ac4d-fd96-4b1e-892a-d4fab818ea2a" at path "vehicle"',
name: 'CastError',
type: 'ObjectId',
value: ["b205ac4d-fd96-4b1e-892a-d4fab818ea2a"],
path: 'vehicle' }
Credo che questo errore abbia senso poiché ora utilizzo le stringhe che sono più lunghe dei tipici ID oggetto Mongo. Senza avere il riferimento all'ObjectID, non credo che sarò in grado di fare il populate()
oggetti di riferimento da altre collezioni. Suppongo che potrei semplicemente non fare riferimento agli altri oggetti nidificati nelle definizioni dello schema, tuttavia non mi piace questo approccio poiché ritengo che perderò molti dei benefici dell'utilizzo dell'ODM. Qualche altro pensiero?
Si potrebbe semplificare questo un po ': '_id : {type: String, default: uuid.v1} ' –
@AdamC il tuo suggerimento renderebbe l'uuid generato costante durante la vita di questo oggetto. –
No, va bene. 'default: uuid.v1()' avrebbe quel problema, ma non 'default: uuid.v1'. – JohnnyHK