node.js - conectar - Mangosta no guarda datos en el MongoDB
conectar node js con mongodb (3)
Debajo hay un objeto literal que intento guardar para MongoDB. Se define dentro del archivo app.js que es un servidor Express. Como el objeto está codificado en el servidor, asumí que se guardará una nueva copia en el DB cada vez que ejecute el servidor, o al menos el documento se guardará una vez, y se anulará o se dejará sin cambios al detectar que el el nuevo documento es idéntico al que se guardó en la última ejecución del servidor. Para mi asombro, no solo no se crean copias dentro de MongoDB, sino que el documento no se guarda en absoluto. Sin embargo, la colección de ''noticias'' ha sido creada, como se verifica con mongo shell ''show collections''. Además, no recibo ningún error en la función de devolución de llamada. También probé Model.create (doc, fn) dentro de mi ruta Express ''/ news'', pero tampoco funciona (el documento debe guardarse cada vez que el cliente llame a la ruta ''/ news'', pero no es). ¿Qué me estoy perdiendo?
Por favor, lea mis anotaciones marcadas con "<-" para ver qué otros problemas o comportamientos inesperados encuentro. Estaré muy agradecido si pudieras abordar esos también en tu respuesta.
var express = require(''express'')
, routes = require(''./routes'')
, user = require(''./routes/user'')
, http = require(''http'')
, path = require(''path'')
, fs = require(''fs'');
// Defining connection to the database:
var mongoose = require(''mongoose'').
connect("mongodb://localhost:27017/my-test-db"),
db = mongoose.connection;
var Schema = mongoose.Schema;
var ObjectID = Schema.ObjectId;
// Setting up the debug flag:
mongoose.set(''debug, true'');
// Logging connection:
db
.on(''error'', console.error.bind(console, ''DB connection error.''))
.once(''open'', console.log.bind(console, ''DB Connection established.''));
// Defining MongoDB schemas:
var usr = new Schema({
first: String,
last: String
});
var newsSchema = new Schema({
headline: String,
bd: String,
imgURI: String,
imgThumbURI: String,
imgCaption: String,
addedOn: Date,
addedBy: {
type: ObjectID,
ref: ''usr''
}
// On user action ''save'' populate the addedOn and addedBy fields before the news article is actually saved to the DB:
newsSchema.pre(''save'', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
});
// Indexing important fields:
usr.index({last: 1});
newsSchema.index({headline: 1});
//Adding the News model:
var News = mongoose.model(''news'', newsSchema);
var nws1 = new News({
headline: "Test news Headline",
bd: "Test news body. Test news body. Test news body. Test news body. Test news body. ",
imgURI: encodeURI("images/news/img.jpg"),
imgThumbURI: encodeURI("images/news/thumbs/img.jpg"),
imgCaption: "Test news image caption.",
addedOn: new Date(),
addedBy: {first: "Admin", last: "Admin"}
});
nws1.save(function(err, news){
if(err) return console.error("Error while saving data to MongoDB: " + err); // <- this gets executed when there''s an error
console.error(news); // <- this never gets logged, even if there''s no error.
});
var app = express();
// all environments
app.set(''port'', process.env.PORT || 3000);
app.set(''views'', path.resolve(__dirname + ''/public''));
app.set(''view engine'', ''html'')
.engine(''html'', function(path, options, fn){
if(''finction'' == typeof options){
fn = options, options = {};
}
fs.readFile(path, ''utf8'', fn);
});
app.use(express.favicon());
app.use(express.logger(''dev''));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session());
app.use(express.static(path.join(__dirname, ''public'')));
http.createServer(app).listen(app.get(''port''), function(){
console.log(''Express server listening on port '' + app.get(''port''));
});
Gracias por tu tiempo
Atentamente
Jared
Encontré algunos problemas al tratar de reproducir esto localmente.
No está llamando a next () en newsSchema.pre (''guardar'')
Debiera ser
newsSchema.pre(''save'', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = adminUser;
next();
});
También debes asegurarte de que estás conectado a la base de datos antes de hacer cualquiera de estas cosas, no estás seguro si eres o no, ya que no vi esa parte del código.
Parece que el problema está en el middleware de guardar de su esquema de noticias.
newsSchema.pre(''save'', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
});
Su función recibe una "siguiente" devolución de llamada que debe ejecutar para que la mangosta sepa que ya terminó y que está listo para guardar el documento. Como no lo está llamando, podría explicar por qué no obtiene nada guardado, y tampoco errores.
Intenta simplemente llamar a continuación así:
newsSchema.pre(''save'', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
next();
});
Mi código era diferente, pero aparentemente mi resultado era el mismo: al parecer, no estaba guardando para Mongo a pesar de la llamada .save. SIN EMBARGO, el ahorro realmente estaba teniendo lugar, simplemente no me di cuenta de lo que significan algunos de los parámetros de Mongoose, y que toma algunas libertades formando su nombre de colección.
Más específicamente, cuando usas:
mongoose.model(''MyModelName'', invitationSchema);
para formar su nombre de colección, su nombre de modelo se convierte en minúsculas y se agrega una "s" (si no está allí). Ver también http://samwize.com/2014/03/07/what-mongoose-never-explain-to-you-on-case-sentivity/
Si lo desea, puede omitir estas convenciones de nomenclatura de colecciones hasta cierto punto utilizando un parámetro de nombre de colección al crear el esquema. Ver http://mongoosejs.com/docs/guide.html#collection
Aquí está el mío:
const modelName = "SharingInvitation";
const collectionName = modelName + "s";
const numberOfHoursBeforeExpiry = 24;
var expiryDate = new Date ();
expiryDate.setHours(expiryDate.getHours() + numberOfHoursBeforeExpiry);
var invitationSchema = new Schema({
// _id: (ObjectId), // Uniquely identifies the invitation (autocreated by Mongo)
// gives time/day that the invitation will expire
expiry: { type: Date, default: expiryDate },
// The user is being invited to share the following:
owningUser: ObjectId, // The _id of a PSUserCredentials object.
capabilities: [String] // capability names
}, { collection: collectionName });