$ unwind两次,如何从第一次放松开始?

时间:2014-02-26 22:03:43

标签: mongodb mongodb-query aggregation-framework

我有一个mongo查询,有两个unwinds来获取一个章节数组。我需要得到当前章节的故事“slug”。我尝试在$ project部分中使用“story.slug”:1,但这只是让我返回了一系列用户拥有的slu ..

mongo文档如下所示:

{
    name: 'Test User',
    slug: 'test_user',
    email: 'test@test.com',
    password: 'test',
    story: [
    {
      title: 'Story Title',
      blurb: 'Epic story of a girl',
      slug: 'epic_story_of_a_girl', // Need this ....
      active: true,
      chapters: [{
        title: 'Story',
        chapter: '1',
        content: 'This is the story of a girl. Cried a river and drowned the whole world.',
        slug: '1',
      }]
}

我的mongo查询如下所示:

db.users.aggregate([

    {$project: {
         email: 1,
         name: 1,
         slug: 1,
         chapters: "$story.chapters"
     }}, 

    {$unwind: "$chapters"},
    {$unwind: "$chapters"}, 
    {$match: {"chapters.active": true}},
    {$sort: {"chapters._id": -1}},
    {$limit: 20}
])

结果如下:

{
         "name" : "Test User",
         "slug" : "test_user",
         "email" : "test@test.com",
         "chapters" : {
                 "title" : "Story",
                 "chapter" : "1",
                 "content" : "This is the story of a girl. Cried a river and drowned the whole world.",
                 "slug" : "1"
         }
 }

但我希望结果看起来像这样或类似,我不知道如何。

{
         "name" : "Test User",
         "slug" : "test_user",
         "email" : "test@test.com",
         "storySlug": "epic_story_of_a_girl" // This thing
         "chapters" : {
                 "title" : "Story",
                 "chapter" : "1",
                 "content" : "This is the story of a girl. Cried a river and drowned the whole world.",
                 "slug" : "1"
         }
 }

1 个答案:

答案 0 :(得分:1)

是的,我认为你在第一个投影阶段做了一些偏离。那似乎是在绊倒你。请考虑以下事项:

db.users.aggregate([

    // Try and put a $match phase in here to at least narrow down the items
    // Your later condition is valid even if we are going to get the whole arrays
    {$match: {"chapters.active": true}},

    // First you unwind the story array   
    {"$unwind": "$story"},

    // Then you unwind the chapters array within
    {"$unwind": "$story.chapters"},

    // Match again to "just" get only the active chapters
    {"$match": {"chapters.active": true}},

    // Project into your form
    {"$project": {
        "_id": 0,
        "name": 1,
        "email": 1,
        "storySlug": "$story.slug",
        "activeChapter": "$story.chapters"
    }},         

    // Let's stop here so you can look
    {"$limit": 1}
 ])

如果您一次一个“有效”章节,那就没关系了,但是否则您需要使用群组进行规范化。这与$ project

是可以互换的
    {"$group": {
        "_id": {
            "name": "$name",
            "email": "$email",
            "storySlug": "$story.slug"
        },
        "chapters": {"$push": "$story.chapters" }
    }}         

希望能够解决问题。