Returns an associative array instead of an array of documents in mongoose

Suppose I have a Word model with this schema

var Word = new Schema({ name: { type: String, required: true }, disambiguation: String, partOfSpeech: { type: ObjectId, ref: "PartOfSpeech", required: true }, attributes: [{ type: ObjectId, ref: "Attribute"}], root: [{ type: ObjectId, ref: "Word"}], language: { type: ObjectId, ref: "Language", required: true } }); 

I want to execute a query that returns an object, with word names as keys with and values ​​as arrays of documents containing words with the corresponding name.

As an example, here is a conclusion that I would like. Most fields are omitted for brevity.

 { stick: [{ _id: "5024216f6df57b2b68834079", partOfSpeech: "noun" }, { _id: "678451de6da54c2b68837345", partOfSpeech: "verb" }], dog: [{ _id: "47cc67093475061e3d95369d", partOfSpeech: "noun" }] } 

This way, I can have random access to the list of words, so I do not need to iterate over it many times. Is there a built-in way to do this in mongoose?

+4
source share
3 answers

You cannot do this directly with Mongoose, but if you stream , the query results you can create your desired associative array quite easily:

 var stream = Word.find().stream(), results = {}; stream.on('data', function(doc) { if (results.hasOwnProperty(doc.name)) { results[doc.name].push(doc); } else { results[doc.name] = [doc]; } }).on('error', function(doc) { // Error handling... }).on('close', function(doc) { // All done, results object is ready. }); 
+2
source
 Word.find().lean().exec(function (err, docs) { // docs are plain javascript objects instead of model instances }); 
+1
source

You can use the reduce function to "reindex" any array into the dictionary. I use underscore in my example, but I would think that with a little tweaking it can work directly in the mongoose. http://techishard.wordpress.com/2012/04/22/reducing-an-array-of-objects-to-a-hash-using-a-property-as-key/

 _.reduce (foo, function (reduced, item) { reduced[item.name] = item; return reduced; }, {}); 
+1
source

All Articles