Edited at

Accessing nested document in mongodb using mgo

More than 3 years have passed since last update.

例えばこんな documentあります



{
"_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 したい時に、どうしたらいい?

{

"_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

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

{

"_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


mongos> db.data_stores.aggregate([
{$match:{_id:ObjectId("56149e20cc1cb46e80170809")}},
{$unwind:"$statuses"},
{$unwind:"$statuses.actions"},
{$match:{"statuses.actions._id":ObjectId("56149e38cc1cb46e80170833")}}
]).pretty()

{

"_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で書くとクエリが

    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)