MongoDBのエンティティのネストされた配列を更新する簡単な方法はありますか?アプリケーションからDB呼び出しを行うためにMongoDB C# Driver
を使用しています。以下に例を示します。Student
コレクションがあります。各ドキュメントにはCourse
のネストされた配列があり、いくつかの必要なフィールドが入力されており、Course
自体は次のような個別のコレクションです。
{
"_id": "234dssfcv456",
"Name": "Jean Douglas",
"Age": 32,
"Courses":
[
{
"_id": "1234",
"Name": "Computer Science",
"Level": "Basic"
},
{
"_id": "3456",
"Name": "Bio Science",
"Level": "Intermediate"
}
]
}
以下のようなインデックスでネストされたエンティティを更新できることはわかっていますが、インデックスがわからず、ネストされたCourse
オブジェクトId
のみがわかります。
db.College.Student.update(
{"Student._id": "234dssfcv456"},
{$set: {
"Student.$.Courses.1.Level": "Basic"
}}
現在、ネストされたコースの配列全体を読み取っています->アプリケーションの最後で変更を行っています->次に、配列全体をfiledname "Courses"
で更新用に渡します。これにより、既存の配列が渡された配列に置き換えられます。
しかし、考えていたのですが、配列内の1つのエンティティをId
で更新できる方法はありますか。提案してください。
*** 関連質問セクションの右側はすべて、オブジェクトアイテムのインデックスを使用してオブジェクトのネストされた配列を更新することを示していますが、これは私には不可能です。
Mongo Shell:
> db.students.find( {_id:"234dssfcv456", "Courses._id":"1234"} ).pretty()
> db.students.update( {_id:"234dssfcv456", "Courses._id":"3456"}, { $set: { "Courses.$.Level" : "Updated" } } )
C#Mongoスキーマ:
public class Student {
[BsonId]
[BsonRepresentation(BsonType.String)]
public string Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Course[] Courses { get; set; }
}
public class Course {
[BsonId]
[BsonRepresentation(BsonType.String)]
public string Id { get; set; }
public string Name { get; set; }
public string Level { get; set; }
}
位置演算子 のMongoドキュメントを検索します。バージョン2.2.3.3以降のドライバーで使用しています:
var _client = new MongoClient(@"....");
var _database = _client.GetDatabase("...");
var _students = _database.GetCollection<Student>("students");
var filter = Builders<Student>.Filter;
var studentIdAndCourseIdFilter = filter.And(
filter.Eq(x => x.Id, "234dssfcv456"),
filter.ElemMatch(x => x.Courses, c => c.Id == "1234") );
// find student with id and course id
var student = _students.Find(studentIdAndCourseIdFilter).SingleOrDefault();
// update with positional operator
var update = Builders<Student>.Update;
var courseLevelSetter = update.Set("Courses.$.Level", "Updated Level");
_students.UpdateOne(studentIdAndCourseIdFilter, courseLevelSetter);
update.Set("Courses.$.Level", "Updated Level");
の代わりに、次のようにすることもできます。
update.Set(x => x.Courses[-1].Level, "Updated Level");