我有一系列博客,其中的帖子嵌入到:
db.blogs.insert({
name: 'Smashing Magazine',
url: 'http://www.smashingmagazine.com/',
posts: [{
date: new Date('2013-05-10'),
title: 'How To Avoid Duplicate Downloads In Responsive Images',
url: 'http://mobile.smashingmagazine.com/2013/05/10/how-to-avoid-duplicate-downloads-in-responsive-images/',
tags: ['Responsive Design', 'Techniques']}]
});
我想运行一个查询,返回所有帖子,其中包含一个额外的布尔字段,表示每个帖子是否存在特定标签。这就是我尝试过但失败的原因:
db.blogs.aggregate(
{$unwind: "$posts"},
{$project: {
name: 1,
date: "$posts.date",
title: "$posts.title",
// isResponsiveDesign should be true or false based on if the post is tagged as "Responsive Design" or not
isResponsiveDesign: {$and: [{"$posts.tags": 'Responsive Design'}]}
}}
);
编写此查询的正确方法是什么?
答案 0 :(得分:1)
我唯一可以把它想象成聚合的方式结果是啰嗦。将查询建模为map-reduce操作可能更容易/更简单。无论如何,我们走了:
db.blogs.aggregate([
{$unwind: '$posts'},
// Grab the only fields we'll need
{$project: {
name: 1,
posts: 1
}},
// Generate a document for each tag within each post
{$unwind: '$posts.tags'},
// Add an attribute to post tags which are equivalent to our search
// term
{$project: {
name: 1,
posts: 1,
isResponsiveDesign: {
$cond: [{$eq: ['$posts.tags', 'Responsive Design']}, 1, 0]
}
}},
// Recombine so that we have one document per post. Use '$max' to
// simulate a boolean OR between two documents' binary
// 'isResponsiveDesign' fields
{$group: {
_id: '$_id',
posts: {$push: '$posts'},
isResponsiveDesign: {$max: '$isResponsiveDesign'}
}}
]);
这是使用您提供的示例数据进行聚合的输出。我添加了一个愚蠢的文档副本,删除了“响应式设计”标签,只是为了测试。
{
"result" : [
{
"_id" : ObjectId("51901e3a8fa65c820b9aae85"),
"posts" : [
{
"date" : ISODate("2013-05-10T00:00:00Z"),
"title" : "How To Avoid Duplicate Downloads In Responsive Images",
"url" : "http://mobile.smashingmagazine.com/2013/05/10/how-to-avoid-duplicate-downloads-in-responsive-images/",
"tags" : null
},
{
"date" : ISODate("2013-05-10T00:00:00Z"),
"title" : "How To Avoid Duplicate Downloads In Responsive Images",
"url" : "http://mobile.smashingmagazine.com/2013/05/10/how-to-avoid-duplicate-downloads-in-responsive-images/",
"tags" : "Techniques"
}
],
"isResponsiveDesign" : 0
},
{
"_id" : ObjectId("5190190f6ab03ad381d1cb0f"),
"posts" : [
{
"date" : ISODate("2013-05-10T00:00:00Z"),
"title" : "How To Avoid Duplicate Downloads In Responsive Images",
"url" : "http://mobile.smashingmagazine.com/2013/05/10/how-to-avoid-duplicate-downloads-in-responsive-images/",
"tags" : "Responsive Design"
},
{
"date" : ISODate("2013-05-10T00:00:00Z"),
"title" : "How To Avoid Duplicate Downloads In Responsive Images",
"url" : "http://mobile.smashingmagazine.com/2013/05/10/how-to-avoid-duplicate-downloads-in-responsive-images/",
"tags" : "Techniques"
}
],
"isResponsiveDesign" : 1
}
],
"ok" : 1
}