2012-08-23 16 views
5

Próbuję iterować po różnych identyfikatorach nad kolekcją w nodejs. Coś, co będzie działać jak w poniższym kodzie:Mongoose - Przejdź do następnego elementu

//Callbacks removed for readability 

var thisPost = mongoose.model('Post').findOne({tags: 'Adventure'}); 
console.log(thisPost.title); // 'Post #1 - Adventure Part 1' 

var nextPost = thisPost.next({tags: 'Adventure'); 
console.log(nextPost.title); // 'Post 354 - Adventure Part 2' 

Najlepszy pomysł tak daleko byłoby dodać LinkedList do mojego schematu, więc mogłem zadzwonić find() nad moim kolejnym odniesieniem do konkretnego ID ale miałem nadzieję na coś mniej "trudny", który pozwoliłby mi użyć tego odnośnika Mongoose (thisPost) jako kursora, od którego można rozpocząć moje find().

Dzięki

EDIT: iteracja jest przeznaczona do pracy na wielu zapytań stron. Lepszy przykład:

//Callbacks removed for readability 

//User 'JohnDoe' visits the website for the first time 
var thisQuote = mongoose.model('Quote').findOne().skip(Math.rand()); 
res.send(thisQuote); // On page output, JohnDoe will see the quote 42 
//Saving the current quote cursor to user's metadatas 
mongoose.model('User').update({user: 'JohnDoe'}, {$set: {lastQuote: thisQuote }}); 

//User 'JohnDoe' comes back to the website 
var user = mongoose.model('User').findOne({user: 'JohnDoe}); 
var thisQuote = user.lastQuote.next(); 
res.send(thisQuote); // On page output, JohnDoe will see the quote 43 
//Saving the current quote cursor to user's metadatas 
mongoose.model('User').update({user: 'JohnDoe'}, {$set: {lastQuote: thisQuote }}); 

//And so on... 

Odpowiedz

11

Możecie zajrzeć do możliwości streamingu Mongoose za:

var stream = mongoose.model('Post').find({tags: 'Adventure'}).stream(); 

// Each `data` event has a Post document attached 
stream.on('data', function (post) { 
    console.log(post.title); 
}); 

QueryStream, który jest co stream() powraca, dziedziczy Node.js' Stream, więc można zrobić kilka ciekawych rzeczy używając pause i resume jeśli ciebie potrzebować.

[Edytuj]

Teraz rozumiem Twoje pytanie nieco bardziej, powiedziałbym, że jest to prawdopodobnie QueryStream nie co chcesz używać. Pracowałem nad tym trochę dzisiaj i otrzymałem działające rozwiązanie pod adresem https://gist.github.com/3453567; po prostu sklonuj Gist (git://gist.github.com/3453567.git), uruchom npm install, a następnie node index.js i powinieneś być w stanie odwiedzić stronę pod numerem http://localhost:3000. Odświeżanie strony powinno dać ci "następny" cytat, a kiedy dojdziesz do końca, powinno się zawijać.

To działa, ponieważ od paru rzeczy:

Najpierw zapisać reference do „ostatniego widzianego” zacytować użytkownika w ich danych:

var UserSchema = new mongoose.Schema({ 
    user: String, 
    lastQuote: { type: mongoose.Schema.Types.ObjectId, ref: 'Quote' } 
}); 

Teraz gdy robimy User.findOne().populate('lastQuote') atrybut lastQuote na Użytkownika, który zostanie zwrócony, będzie faktyczny obiekt Cytat, do którego odnosi się wartość pola zapisanego w MongoDB (który jest ObjectId).

Możemy zadzwonić next() na ten cytat obiektu z powodu następującego kodu:

QuoteSchema.methods.next = function(cb) { 
    var model = this.model("Quote"); 
    model.findOne().where('_id').gt(this._id).exec(function(err, quote) { 
    if (err) throw err; 

    if (quote) { 
     cb(null, quote); 
    } else { 
     // If quote is null, we've wrapped around. 
     model.findOne(cb); 
    } 
    }); 
}; 

To jest ta część, która znajduje się następny cytat albo owija wokół pierwszego cytatu.

Zapoznaj się z kodem i daj mi znać, jeśli masz jakieś pytania.

+0

Nie użyłem tej wersji na końcu, ale tak, sądząc z dokumentacji, strumienie są najlepszym sposobem na zrobienie tego, co chcę. Chociaż nie będę go używać z wielu powodów zależnych od aktualnej architektury kodu mojej aplikacji :) – red

+0

Zmodyfikowałem swoją odpowiedź na podstawie Twojej aktualizacji. –

+0

Wow. Zaimplementowałam to wczoraj, korzystając z połączonej listy w mojej bazie danych, ale twoja odpowiedź jest tak prosta, że ​​bardzo się wstydzę, że sama o tym nie pomyślałam. Kudos za swoje myślenie i milion dziękuję za odpowiedź :) – red

Powiązane problemy