2013-08-15 15 views
6


Poniżej znajduje się literał obiektu, który próbuję zapisać do MongoDB. Jest zdefiniowany w pliku app.js, który jest serwerem Express. Ponieważ obiekt jest zakodowany na stałe w serwerze, moim założeniem było, że nowa kopia będzie zapisywana do bazy danych za każdym razem, gdy uruchomię serwer, lub przynajmniej dokument zostanie zapisany jeden raz, i zostanie przesłonięty lub pozostanie niezmieniony po wykryciu, że nowy dokument jest identyczny z zapisanym podczas ostatniego uruchomienia serwera. Ku mojemu zdziwieniu nie tylko kopie są tworzone w MongoDB, ale dokument nie jest w ogóle zapisywany. Została jednak utworzona kolekcja "news", która została zweryfikowana w Mongo Shell 'show collections'. Ponadto nie otrzymuję żadnego błędu w funkcji wywołania zwrotnego. Próbowałem również Model.create (doc, fn) na mojej trasie Express/news, ale to też nie działa (dokument powinien być zapisany za każdym razem, gdy trasa "/ news" jest wywoływana przez klienta, ale nie jest). czego mi brakuje?
Przeczytaj moje adnotacje oznaczone "< -", aby zobaczyć, jakie inne problemy lub nieoczekiwane zachowanie napotykam. Będę bardzo wdzięczny, jeśli mógłbyś odpowiedzieć na to również w swojej odpowiedzi.Mongoose nie zapisuje danych do MongoDB

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')); 
}); 

Dziękuję za poświęcony czas
poważaniem
Jared

+1

Czy wywołanie 'mongoose.connect' aby połączyć się z bazą danych gdzieś poza tym kodem? – JohnnyHK

+0

@JohnnyHK Tak, jestem. Zobacz zaktualizowane pytanie. Zawarłem odpowiedni kod. –

Odpowiedz

24

Wygląda na to, że problem jest w News schematu za zaoszczędzenia middleware.

newsSchema.pre('save', function(next){ 
    if(!this.addedOn) this.addedOn = new Date(); 
    if(!this.addedBy) this.addedBy = {first: "admin", last: "admin"}; 
}); 

Twoja funkcja odbiera „obok” zwrotnego, które należy wykonać, aby pozwolić mangusta wiedzieć, że są zrobione i gotowe, aby zapisać dokument. Ponieważ tego nie nazywasz, może to wyjaśnić, dlaczego nic nie zostało zapisane, a także nie ma błędów.

Spróbuj tylko nazywając obok tak:

newsSchema.pre('save', function(next){ 
    if(!this.addedOn) this.addedOn = new Date(); 
    if(!this.addedBy) this.addedBy = {first: "admin", last: "admin"}; 
    next(); 
}); 
+0

Dziękuję bardzo za supershabam. Tego właśnie mi brakowało. Taki drobiazg, a jednak tak bardzo boli (wiele na czas zmarnowałem, próbując samodzielnie to rozgryźć). Mnóstwo mojej reputacji - miłości do ciebie partnera. –

+0

Ah za *** i& !!! wzgląd! Utknąłem na tym samym bugie przez 4 godziny !!! Dziękuję Ci!!!! –

+0

O mój boże, nie mogę ci wystarczająco podziękować. Popsułem przenoszenie kodu, a moje wywołanie "next()" było po prostu "następne", co oczywiście nigdy nie wykonało wywołania zwrotnego. Utknąłem na tym także przez wiele godzin. DZIĘKUJĘ –

4

znalazłem kilka problemów, gdy próbuje odtworzyć to lokalnie.

Nie jesteś wywołanie next() w newsSchema.pre („zapisz”)

Powinny być

newsSchema.pre('save', function(next){ 
    if(!this.addedOn) this.addedOn = new Date(); 
    if(!this.addedBy) this.addedBy = adminUser; 
    next(); 
}); 

Należy również upewnić się, że komputer jest podłączony do db przed wykonaniem któregokolwiek z tych rzeczy, nie jestem pewien, czy jesteś, czy nie, ponieważ nie widziałem tej części kodu.

+3

Fantastyczne. Właśnie tego mi brakowało. +1 dla ciebie, ale moja "zaakceptowana odpowiedź" trafia do SuperShabam, ponieważ zawiera on więcej szczegółów na temat problemu. Również on potrzebuje więcej punktów reputacji :). W każdy sposób, wielkie dzięki. –

0

Mój kod był inny, ale mój wynik był podobno taki sam: Najwyraźniej nie zapisywałem Mongo pomimo połączenia .save. JEDNAK, faktycznie miało to miejsce, po prostu nie zdawałem sobie sprawy z tego, co oznaczają niektóre parametry Mongoose i że wymaga to pewnych swobód tworzących nazwę twojej kolekcji.

Dokładniej, gdy używasz:

mongoose.model('MyModelName', invitationSchema); 

tworząc swoją nazwę kolekcji, nazwę modelu pobiera konwertowane na małe litery, a „s” zostaje załączony (jeśli nie istnieje). Zobacz także: http://samwize.com/2014/03/07/what-mongoose-never-explain-to-you-on-case-sentivity/ Możesz, jeśli chcesz, ominąć te konwencje nazewnictwa kolekcji w pewnym zakresie, używając parametru nazwy kolekcji podczas tworzenia schematu.Zobacz http://mongoosejs.com/docs/guide.html#collection

Oto moje:

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 }); 
Powiązane problemy