Mongoose返回数组,每个元素的值旁边都有.count
Mongoose return array with .count of each element alongside each element value?
现在,这个expressJS调用为mongoose .count提供逗号分隔的值,该值导致.find,但分别返回计数和值。
我如何将结果构建为一个数组,其中包含每个搜索标记+有多少个故事具有该标记,其方式看起来像这样(将与模板引擎循环):
tags: [{tag: tag1, count: 4}, {tag: tag2,Count: 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
这里不是很清楚"tags"实际上是如何出现在您的文档中,它只是一个字段或数组中的单个值。无论如何,如果你打算计数标签,那么你最好使用聚合框架,而不是在代码中"后处理"你的.find()
结果。
第一个使用"tags"作为单个字段值:
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()
操作,但也不确定您是否真的需要它。
如果"tags"实际上是一个数组,那么你需要做一些不同的事情,因为你需要从数组中提取匹配项以获得计数:
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
操作符和其他操作符之前过滤数组来简化一点。
为了更清晰,我把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 });
}
);
它的优点是在调用 $unwind
之前从数组中删除你不想要的"标签",这可以根据有多少数组元素来加速匹配。
当然,虽然上面的示例在获取文档计数方面与第一个示例有所不同,但如果您更喜欢组合的结果,您仍然可以将其包含在一个额外的分组中:
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] );
}
);
同样,不需要像 $size
这样的操作符,也可以通过不同的分组来获得单个结果中的totalCount,甚至不需要 $addToSet
但是总的方向是,如果你要计算"标签",这是你基本上想要去的地方,因为你可以让服务器为你做这项工作
- CKEditor Widget-阻止编辑可编辑元素本身
- 如何设置html元素填充的动画
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 使用clickToggle并在单击另一个元素时关闭元素
- 单击时将焦点更改为元素
- 表追加而不附加最后一个元素
- 如何在jQuery中获取元素的形式
- 我可以获得相对于被点击元素的确切点击位置吗
- 在函数中添加数组元素的数值
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 将视口底部滚动到元素底部
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 比较两个array's元素并返回count JavaScript
- Count数组中元素的个数(不是长度)
- Count数组中两个元素小于或等于一个求和值的次数
- Mongoose返回数组,每个元素的值旁边都有.count
- Count JavaScript元素的数量
- Javascript:如何只对可见元素执行count