2012-01-05 8 views
19

Comment puis-je ajouter un schéma à un autre schéma? Cela ne semble pas être valide:Schéma Mongoose dans le schéma

var UserSchema = new Schema({ 
    name  : String, 
    app_key  : String, 
    app_secret : String 
}) 



var TaskSchema = new Schema({ 
    name   : String, 
    lastPerformed : Date, 
    folder   : String, 
    user   : UserSchema 
}) 

J'ai vérifié le site et il montre comment déclarer pour un tableau, mais pas pour seule.

Merci

+0

Faites-vous une jointure entre deux collections ou souhaitez-vous les stocker en haut de la tâche? –

Répondre

26

Il existe plusieurs façons de procéder. Le plus simple est ceci:

var TaskSchema = new Schema({ 
    name   : String, 
    lastPerformed : Date, 
    folder   : String, 
    user   : Schema.ObjectId 
}); 

Il vous suffit de vous assurer que votre application est en train d'écrire cet identifiant et l'utiliser dans les requêtes pour aller chercher « en rapport » les données nécessaires.

Ceci est bien lors de la recherche des tâches par nom d'utilisateur, mais plus lourd lors de l'interrogation de l'utilisateur par ID de tâche:

// Get tasks with user id 
Task.find({user: user_id}, function(err, tasks) {...}); 

// Get user from task id 
Task.findById(id, function(err, task) { 
    User.findById(task.user, function(err, user) { 
    // do stuff with user 
    } 
} 

Une autre façon est de profiter de la fonction de mangouste populate pour simplifier vos requêtes. Pour obtenir cela, vous pouvez faire ce qui suit:

var UserSchema = new Schema({ 
    name  : String, 
    app_key  : String, 
    app_secret : String, 
    tasks  : [{type: Schema.ObjectId, ref: 'Task'}] // assuming you name your model Task 
}); 

var TaskSchema = new Schema({ 
    name   : String, 
    lastPerformed : Date, 
    folder   : String, 
    user   : {type: Schema.ObjectId, ref: 'User'} // assuming you name your model User 
}); 

Avec cela, votre requête pour tous les utilisateurs, y compris les tableaux de leurs tâches pourrait être:

User.find({}).populate('tasks').run(function(err, users) { 
    // do something 
}); 

Bien sûr, cela signifie maintenir les ids dans les deux endroits. Si cela vous dérange, il vaut mieux s'en tenir à la première méthode et s'habituer à écrire des requêtes plus complexes (mais toujours assez simples).

+0

merci pour la réponse détaillée. J'ai une autre question, mais je devrais peut-être créer une nouvelle question. – 0xSina

+2

'.run()' a été remplacé par '.exec()' comme il semble –

+0

un autre [link] [1], avec [populate] [2], pourrait vous aider aussi. [1]: http://gistflow.com/posts/46-mongoose-populate [2]: http://mongoosejs.com/docs/populate.html –

8

Et cette solution simple?

var TaskSchema = new Schema({ 
    name   : String, 
    lastPerformed : Date, 
    folder   : String, 
    user   : { 
     name  : String, 
     app_key  : String, 
     app_secret : String 
    } 
}) 
+6

Cela n'éliminerait-il pas la possibilité d'interroger? utilisateurs directement, et potentiellement conduire à des objets utilisateur en cours de duplication à travers de nombreuses tâches? Si vous alliez aplatir le modèle de données à une seule structure, je pense que vous voudriez que UserSchema soit un parent de tâches plutôt que l'inverse. – VictorB

+0

rend le code malpropre. D'où voulait le schéma dans le schéma –

Questions connexes