4

我有一个博客集合,这些帖子嵌入到:

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'}]}
    }}
);

编写此查询的正确方法是什么?

4

1 回答 1

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
}
于 2013-05-12T22:58:30.113 回答