聚集/项目子文档为mongo中的顶级文档 [英] Aggregate/project sub-document as top-level document in mongo

查看:40
本文介绍了聚集/项目子文档为mongo中的顶级文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一个集合中经过几个聚合步骤(流水线步骤)之后,我得到了以下结果:

After a few aggregation steps (pipeline steps) in one of my collections, I'm ending up with the following result:

{
    "_id" : ObjectId("574e7722bffe901713d383bb"),
    "eventname" : "Ball Passed",
    "command" : {
        "_id" : ObjectId("57ec6b6f6c61e919b578fe7c"),
        "name" : "Run",
        "strike" : 15,
        "score" : true,
        "duration" : 123
    }
}
{
    "_id" : ObjectId("57ec6b6f6c61e919b578ff8a"),
    "eventname" : "Ball Passed",
    "command" : {
        "_id" : ObjectId("573d688d080cc2cbe8aecbbc"),
        "name" : "Run",
        "strike" : 12,
        "score" : false,
        "duration" : 597
    }
}

哪个好!

但是,在聚合的下一步中,我想得到以下结果:

However, in the next step of the aggregation, I'd like to get the following result:

{
    "_id" : ObjectId("57ec6b6f6c61e919b578fe7c"),
    "name" : "Run",
    "strike" : 15,
    "duration" : 123
}
{
    "_id" : ObjectId("573d688d080cc2cbe8aecbbc"),
    "name" : "Run",
    "strike" : 12,
    "duration" : 597
}

如果您已经注意到,command字段应该成为顶级文档,而command.score应该被跳过.

If you have noticed, the command field should become the top-level document, and command.score should be skipped.

如何一步一步实现呢?如果一步不可能,那么分多个步骤?我想我必须使用$project?

How can I achieve this in a single step? If that is not possible in a single step, then in multiple steps? I guess I've to use $project?

推荐答案

您猜到了,$project允许您这样做:

As you have guessed, $project allows you to do that:

db.col.aggregate([
{
    $project : 
    {
        _id: "$command._id",
        name: "$command.name", 
        strike: "$command.strike", 
        duration: "$command.duration"
    }
}
]).pretty()

我插入了您以前的结果,上面的查询返回了此结果:

I inserted your previous results and the above query returned this:

{
    "_id" : ObjectId("57ec6b6f6c61e919b578fe7c"),
    "name" : "Run",
    "strike" : 15,
    "duration" : 123
}
{
    "_id" : ObjectId("573d688d080cc2cbe8aecbbc"),
    "name" : "Run",
    "strike" : 12,
    "duration" : 597
}

因此使用进行查询 会产生您想要的结果.

So piping your query with this $product should produce the result you are looking for.

如果确切的结构不是您的主要关注点,而是排除少数字段(无需列出所有要包括的字段),则可以使用find()而不是aggregate().

If the exact structure is not your main concern, but rather the exclusion of few fields (wihtout having to list all fields to include), then you may use find() instead of aggregate().

aggregate的产品仅允许您排除_id.这意味着您需要手动列出要包括的所有字段.
注意:自MongoDB 3.4版以来,可以排除$project阶段中的字段(

aggregate's product only lets you exclude _id. This means you need to manually list all fields to include.
Note: Since version 3.4 of MongoDB it is possible to exclude fields in $project phase (https://docs.mongodb.com/manual/reference/operator/aggregation/project/#exclude-fields)

find,但是,您可以列出要隐藏的字段.

find however, lets you list the fields to hide.

(1)您可以使用

(2)即使结构不完全符合您的要求,您仍然可以执行find查询并隐藏字段:

(2) Even though the structure won't be exactly as you'd like, you'll then be able to do a find query and hide fields:

db.commands.find({}, {_id:0, "command.score":0, eventname:0}).pretty()

它返回此值,这与您要查找的内容非常接近:

It returns this, which is pretty close to what you were looking for:

{
    "command" : {
        "_id" : ObjectId("57ec6b6f6c61e919b578fe7c"),
        "name" : "Run",
        "strike" : 15,
        "duration" : 123
    }
}

这篇关于聚集/项目子文档为mongo中的顶级文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆