Accessing nested document in mongodb using mgo


例えばこんな documentあります

```json

{
	"_id" : ObjectId("56149e20cc1cb46e80170809"),
	"name_jp" : "",
	"name_en" : "app1",
	"application_id" : "56149e20cc1cb46e8017080a",
	"fields" : [
		{
			"colnameen" : "age",
			"colnamejp" : "age",
			"id" : "g9C3r",
			"name" : "age",
			"type" : "string"
		}
	],
	"statuses" : [

		{
			"_id" : ObjectId("56149e20cc1cb46e80170830"),
			"name_jp" : "deleted",
			"name_en" : "deleted",
			"actions" : [ ]
		},
		{
			"_id" : ObjectId("56149e20cc1cb46e80170832"),
			"name_jp" : "checking",
			"name_en" : "checking",
			"actions" : [
				{
					"_id" : ObjectId("56149e38cc1cb46e80170833"),
					"name_jp" : "",
					"name_en" : "new checking",
					"name" : "",
					"next_status" : "56149e20cc1cb46e8017082f",
					"update_fields" : [
						{
							"field_id" : "g9C3r",
							"is_mandatory" : false,
							"is_editable" : true
						},
						{
							"field_id" : "9p3SY",
							"is_mandatory" : false,
							"is_editable" : true
						}
					]
				},
				{
					"_id" : ObjectId("56149e52cc1cb46e80170834"),
					"name_jp" : "",
					"name_en" : "delete checking",
					"name" : "",
					"next_status" : "56149e20cc1cb46e80170830",
					"update_fields" : [
						{
							"field_id" : "g9C3r",
							"is_mandatory" : false,
							"is_editable" : true
						},
						{
							"field_id" : "9p3SY",
							"is_mandatory" : false,
							"is_editable" : true
						},
						{
							"field_id" : "MPd75",
							"is_mandatory" : false,
							"is_editable" : true
						}
					]
				}
			]
		}
	],
	"unread" : 0,
	"created_at" : ISODate("2015-10-07T04:22:56.671Z"),
	"updated_at" : ISODate("2015-10-07T04:22:56.671Z")
}
```

`statuses.actions._id=ObjectId("56149e38cc1cb46e80170833")` select したい時に、どうしたらいい？

```json
{
                    "_id" : ObjectId("56149e38cc1cb46e80170833"),
                    "name_jp" : "",
                    "name_en" : "new checking",
                    "name" : "",
                    "next_status" : "56149e20cc1cb46e8017082f",
                    "update_fields" : [
                        {
                            "field_id" : "g9C3r",
                            "is_mandatory" : false,
                            "is_editable" : true
                        },
                        {
                            "field_id" : "9p3SY",
                            "is_mandatory" : false,
                            "is_editable" : true
                        }
                    ]
                }
```

### Try find #1
```bash
mongos> db.data_stores.find({_id:ObjectId("56149e20cc1cb46e80170809"),"statuses.actions._id":ObjectId("56149e38cc1cb46e80170833")},{"statuses.actions.$":1})
```

```json
{
	"_id" : ObjectId("56149e20cc1cb46e80170809"),
	"statuses" : [
		{
			"_id" : ObjectId("56149e20cc1cb46e80170832"),
			"name_jp" : "checking",
			"name_en" : "checking",
			"actions" : [
				{
					"_id" : ObjectId("56149e38cc1cb46e80170833"),
					"name_jp" : "",
					"name_en" : "new checking",
					"name" : "",
					"next_status" : "56149e20cc1cb46e8017082f",
					"update_fields" : [
						{
							"field_id" : "g9C3r",
							"is_mandatory" : false,
							"is_editable" : true
						},
						{
							"field_id" : "9p3SY",
							"is_mandatory" : false,
							"is_editable" : true
						}
					]
				},
				{
					"_id" : ObjectId("56149e52cc1cb46e80170834"),
					"name_jp" : "",
					"name_en" : "delete checking",
					"name" : "",
					"next_status" : "56149e20cc1cb46e80170830",
					"update_fields" : [
						{
							"field_id" : "g9C3r",
							"is_mandatory" : false,
							"is_editable" : true
						},
						{
							"field_id" : "9p3SY",
							"is_mandatory" : false,
							"is_editable" : true
						},
						{
							"field_id" : "MPd75",
							"is_mandatory" : false,
							"is_editable" : true
						}
					]
				}
			]
		}
	]
}
```

結果が大丈夫ですけど、不要なデータが含まります。使えない

### Try aggregation framework #2

```bash

mongos> db.data_stores.aggregate([
{$match:{_id:ObjectId("56149e20cc1cb46e80170809")}},
{$unwind:"$statuses"},
{$unwind:"$statuses.actions"},
{$match:{"statuses.actions._id":ObjectId("56149e38cc1cb46e80170833")}}
]).pretty()
```
```json
{
	"_id" : ObjectId("56149e20cc1cb46e80170809"),
	"name_jp" : "",
	"name_en" : "app1",
	"application_id" : "56149e20cc1cb46e8017080a",
	"fields" : [
		{
			"colnameen" : "age",
			"colnamejp" : "age",
			"id" : "g9C3r",
			"name" : "age",
			"type" : "string"
		},

	],
	"statuses" : {
		"_id" : ObjectId("56149e20cc1cb46e80170832"),
		"name_jp" : "checking",
		"name_en" : "checking",
		"actions" : {
			"_id" : ObjectId("56149e38cc1cb46e80170833"),
			"name_jp" : "",
			"name_en" : "new checking",
			"name" : "",
			"next_status" : "56149e20cc1cb46e8017082f",
			"update_fields" : [
				{
					"field_id" : "g9C3r",
					"is_mandatory" : false,
					"is_editable" : true
				},
				{
					"field_id" : "9p3SY",
					"is_mandatory" : false,
					"is_editable" : true
				}
			]
		}
	},
	"unread" : 0,
	"created_at" : ISODate("2015-10-07T04:22:56.671Z"),
	"updated_at" : ISODate("2015-10-07T04:22:56.671Z")
}
```

さすがaggregation framework。この結果が使えると思います。

mgoで書くとクエリが

```go
	query := []bson.M{
		{"$match": bson.M{"_id": dataStoreID}},
		{"$unwind": "$statuses"},
		{"$unwind": "$statuses.actions"},
		{"$match": bson.M{
			"statuses.actions._id": actionID,
		}},
	}

	err := c.Pipe(query).One(&dt)
```