I have 2 collections name "Keywords" and "Company", I use MongoDB aggregate framework to retrieve related object._id from "Keywords" collection base on keywords user key in.
After i got the object._id from keywords collection, i want to query and compile a final complete docs from Company collection using the object._id.
I stuck on the part where res.view() run first before the result[] collect all the docs from Company collection.
I need to help to turn my code to Synchronous approach. Please help me. Below are what i did.
Sample of doc from "Keywords" Collection
{
"_id": ObjectID("52ac7130bd40d00a7beb7a29"),
"keyword": "Sunshine",
"object": [
{
"_id": ObjectID("528443ce751fc9b805d640ad"),
"type": "companyName"
}
]
}
Sample of doc from "Company" Collection
{
"_id": ObjectID("528443ce751fc9b805d640ad"),
"name": "Sunshine Plaza",
...
...
...
}
SearchController in SailsJS
var keyWords = req.query.q,
searchKeywords = keyWords.toLowerCase().replace(/[^\w\s]/gi, ' ').split(' '), //For example user key in "Sunshine Plaza"
results = [];
Keyword.native(function(err,collection){
collection.aggregate([
{
$project : {
'_id' : 0,
'keyword' : 1,
'object' : 1
}
}, {
$match : {
'keyword' : {
'$in' : searchKeywords
}
}
} , {
$unwind : '$object'
} , {
$group : {
_id : '$object._id',
count : {
$sum : 1
}
}
} , {
$sort : {
count: -1
}
} , {
$skip : 0
} , {
$limit : 10
}
], function (err, docs){
docs.forEach(function (doc, i){
Company.findOne({
'_id' : doc._id
},function(err,docs){
results.push(docs);
});
});
});
});
res.view({
key : keyWords,
results : results,
layout: "layouts/search"
});
What you're missing is that this isn't blocking code.
So the following
Bob
would happen first. Thenhi
. This is because it doesn't stop.So you should rewrite this part of your code:
To something like the following: