2015-09-01 13 views
5

Próbuję przejść rekursywnie do węzła nth w modelu MongoDB. Oto mój model użytkownika.Jak przechodzić rekursywnie dokument zagnieżdżony w MongoDB

model użytkownika

var UserSchema = new Schema({ 
    firstname : { type: String}, 
    parents:[{type: mongoose.Schema.Types.ObjectId, ref: 'User' }], 
    children:[{type: mongoose.Schema.Types.ObjectId, ref: 'User' }], 
    partner:[{type: mongoose.Schema.Types.ObjectId, ref: 'User' }], 
    sibling:[{type: mongoose.Schema.Types.ObjectId, ref: 'User' }], 
}); 

ja nie wiem jak do generowania strukturę drzewa z tego modelu, jakieś pomysły dotyczące sposobu wdrożenia tego? Używam Mongoose dla modelu, a także sprawdzone głębokie drzewa i zaludnienie nie udało się, ponieważ działa tylko na pierwszy poziom.

Dzięki z góry.

+2

masz przykład swojego zaludnionego dokumentu? – Alex

+0

Głównym problemem związanym z próbą wykonania więcej niż jednego poziomu populacji, w tym przypadku, jest sytuacja, w której użytkownik ma wartość 'parent' odwołującą się do innego użytkownika, a ten użytkownik ma wartość' children' odwołującą się do pierwszego użytkownika. Jeśli spróbujesz automatycznie wypełnić go rekurencyjnie, utworzysz nieskończoną pętlę. Jeśli zaczynałeś od dziecka i wspinałeś się po drzewie, aby pokazać wszystkim rodzicom, powinieneś być bezpieczny, ale nadal musisz śledzić wszystkie identyfikatory użytkowników, aby upewnić się, że nie zrobiłeś tego przypadkowo. użytkownik własny przodek. –

Odpowiedz

4

Najłatwiej jest to zrobić jest użycie Bluebird obietnic, zwłaszcza metody each, props, reduce i map, w zależności od przypadku użycia.

W twoim przypadku, chciałbym zaproponować coś wzdłuż linii

var bluebird = require('bluebird'); 
var mongoose = require('mongoose'); 
var UserModel = mongoose.model('User'); 

function getUser(userId) { 
    return UserModel.findOne({_id: userId}).lean().exec() 
    .then(function(user){ 
     return bluebird.props({ 
     firstName: user.firstName, 
     parents: bluebird.map(user.parents, getUser), 
     children: bluebird.map(user.children, getUser), 
     partner: bluebird.map(user.partner, getUser), 
     sibling: bluebird.map(user.sibling, getUser) 
     }) 
    }); 
} 

// Then call getUser once on the root node, e.g. 
getUser(rootUserObjectId) 
    .then(function(userTree){ 
    console.log(userTree) 
    }) 

Daj mi znać, jak to jest!

+0

Wielkie dzięki, działa dobrze. –

Powiązane problemy