现在,这个expressJS调用将逗号分隔的值提供给导致.find的mongoose .count,但是分别返回计数和值。
我如何将结果构造成一个包含每个搜索标记的数组+具有该标记的故事数量的计数,其方式看起来像这样(用模板引擎循环):
标签:[{tag:tag1,count:4},{tag:tag2, 数:2}]
这里是快递/猫鼬:
router.route('/tag/:tags')
// get the list of tags for userGenerated tags
// accessed by GET at http://localhost:4200/api/v1/tag/tag1,tag2
.get(function(req, res) {
var tags = req.params.tags.split(',');
console.log(tags); // ['tag1', 'tag2']
Story.count( { tags: { $in: tags } }, function (err, count) {
if (err)
res.send(err);
console.log('there is/are %d story(ies) with this/these tag(s)', count);
if (count >= 1) {
Story.find( { tags: { $in: tags } }, 'tags', function(err, stories) {
if (err)
res.send(err);
res.json(storytags);
}); // find and return tags of stories
} // if count >= 1
if (count < 1) {
res.json({ message: count + ' results' });
} // if count < 1
}); // .count
}); // get list of tags
答案 0 :(得分:2)
这里不太清楚&#34;标签&#34;实际上出现在您的文档中,它只是字段中的单个值或数组中的单个值。无论如何,如果你打算计算标签,那么你最好使用aggregation framework而不是&#34;后处理&#34;您的.find()
会产生代码。
首先使用&#34;标签&#34;作为单个字段值:
Story.aggregate(
[
// Match the documents with tags
{ "$match": { "tags": { "$in": tags } }},
// Group the tags with counts
{ "$group": {
"_id": "$tags",
"count": { "$sum": 1 }
}},
// Group to single array with total count
{ "$group": {
"_id": null,
"tags": {
"$push": {
"tag": "$_id",
"count": "$count"
}
},
"totalCount": { "$sum": "$count" }
}},
// Project to remove the _id
{ "$project": {
"_id": 0,
"tags": 1,
"totalCount": 0
}}
],
function(err,result) {
if (err)
res.send(err);
res.json( result[0] );
}
);
这几乎封装了整个列表,因此不需要额外的.count()
操作,但也不确定是否真的需要它。
&#34;标签&#34;实际上是一个数组然后你需要做一些不同的事情,因为你需要从数组中提取你的匹配来获得计数:
Story.aggregate(
[
// Match the documents with tags
{ "$match": { "tags": { "$in": tags } }},
// Unwind the array
{ "$unwind": "$tags" },
// Actually match the tags within the now unwound array
{ "$match": { "tags": { "$in": tags } }},
// Group by each tag
{ "$group": {
"_id": "$tags",
"count": { "$sum": 1 }
}},
// Rename the _id for your output
{ "$project": {
"_id": 0,
"tag": "$_id",
"count": 1
}}
],
function(err,result) {
if (err)
res.send(err);
res.json({ "totalCount": count, "tags": result });
}
);
或者使用MongoDB 2.6或更高版本,您可以通过使用$unwind
运算符和其他人$map
数组$unwind
之前过滤数组来简化一点。
为了清晰起见,我只是在这里展开tags
值
Story.aggregate(
[
// Match the documents with tags
{ "$match": { "tags": { "$in": ["tag1","tag2" } }},
// Filter the array for matches
{ "$project": {
"tags": {
"$setDifference": [
{
"$map": {
"input": "$tags",
"as": "el",
"in": {
"$cond": [
{ "$or": [
{ "$eq": ["$$el", "tag1" ] },
{ "$eq": ["$$el", "tag2" ] },
]},
"$$el",
false
]
}
}
},
[false]
]
}
}},
// Unwind the array already filtered
{ "$unwind": "$tags" },
// Group by each tag
{ "$group": {
"_id": "$tags",
"count": { "$sum": 1 }
}},
// Rename the _id for your output
{ "$project": {
"_id": 0,
"tag": "$_id",
"count": 1
}}
],
function(err,result) {
if (err)
res.send(err);
res.json({ "totalCount": count, "tags": result });
}
);
其优点是删除了&#34;标签&#34;在调用$size
之前你不想从数组中获取,这可以加速匹配,具体取决于有多少数组元素。
当然,虽然以上示例与获取文档计数的第一个示例不同,但如果您更喜欢合并后的结果,仍可以使用一些额外的分组:
Story.aggregate(
[
// Match the documents with tags
{ "$match": { "tags": { "$in": ["tag1","tag2" } }},
// Filter the array for matches
{ "$project": {
"tags": {
"$setDifference": [
{
"$map": {
"input": "$tags",
"as": "el",
"in": {
"$cond": [
{ "$or": [
{ "$eq": ["$$el", "tag1" ] },
{ "$eq": ["$$el", "tag2" ] },
]},
"$$el",
false
]
}
}
},
[false]
]
}
}},
// Unwind the array already filtered
{ "$unwind": "$tags" },
// Group by each tag
{ "$group": {
"_id": "$tags",
"count": { "$sum": 1 },
"docs": { "$addToSet": "$_id" }
}},
// Group to a single array response
{ "$group": {
"_id": null,
"tags": {
"$push": {
"tag": "$_id",
"count": "$count"
}
},
"totalCount": { "$sum": { "$size": "$docs" } }
}
// Rename the fields for your output
{ "$project": {
"_id": 0,
"tags": 1,
"count": 1,
"totalCount"
}}
],
function(err,result) {
if (err)
res.send(err);
res.json( result[0] );
}
);
再次,获得&#34; totalCount&#34;在一个单一的结果中,可以在没有$addToSet
之类的运算符的帮助下完成,实际上没有{{3}}的分组不同。
但是这里的总体方向是,如果您正在计算&#34;标签&#34;,那么您基本上想要去的地方,因为您可以让服务器为您完成工作。