MongoDb .NET для замены строки в массиве с помощью ElemMatch()C#

Место общения программистов C#
Anonymous
MongoDb .NET для замены строки в массиве с помощью ElemMatch()

Сообщение Anonymous »

Я использую драйвер MongoDb .NET (v3.7) для замены строки в массиве с помощью ElemMatch для соответствия элементу строки массива.
Все примеры, которые я вижу относительно ElemMatch(), включают сопоставление объекта в массиве (или списке) объектов.
Могу ли я не использовать те же методы для определения строки в массиве?
Например, я хочу заменить round с треугольником и попробовал следующий код, полагая, что позиционный оператор найдет/ссылается на строку в массиве, которую необходимо изменить. Но, возможно, это невозможно с массивами примитивов?

Код: Выделить всё

var idFilter = Builders.Filter.Eq(d => d.Id, "000000000000000000001002");
var elemMatchFilter = Builders.Filter.ElemMatch(x => x.MyStringArray, "round");
var filtersAnded = Builders.Filter.And(idFilter, elemMatchFilter);
var update = Builders.Update.Set("MyStringArray.[$]", "triangle");
//var update = Builders.Update.Set("MyStringArray.$", "triangle"); // Tried this but gave same exception
UpdateResult result = collection.UpdateOne(filtersAnded, update);
Это приводит к исключению:

Читатель JSON ожидал значение, но нашел «круглое».

Модель данных:

Код: Выделить всё

internal class Sample
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; } = ObjectId.GenerateNewId().ToString();

public int[] MyIntArray { get; set; } = [];
public string[] MyStringArray { get; set; } = [];
}
Код для создания 2 документов:

Код: Выделить всё

public const string Samples = "Samples";
IMongoDatabase? iMongoDatabase = mongoClient.GetDatabase("UpdateArraysTesting");
iMongoDatabase.CreateCollection(Samples);
SamplesCollection = iMongoDatabase!.GetCollection(Samples);

Sample sample = new() {
Id = "000000000000000000001001",
MyIntArray = new int[] { 10, 15 },
MyStringArray = new string[] {"square","box" }
};
SamplesCollection.InsertOne(sample);

sample = new()
{
Id = "000000000000000000001002",
MyIntArray = new int[] { 22, 27 },
MyStringArray = new string[] { "round", "ball" }
};
SamplesCollection.InsertOne(sample);
ОБНОВЛЕНИЕ: Чтобы научить меня использовать ElemMatch(), Aneroid предоставил следующий код. Он предоставил две версии фильтра ElemMatch(), однако первая версия не может найти совпадение, а вторая — успешно.

Код: Выделить всё

var idFilter = Builders.Filter.Eq(d => d.Id, "000000000000000000001002");

// Version 1 does not find a match
var elemMatchFilter_v1 = Builders.Filter.ElemMatch(
x => x.MyStringArray,
Builders.Filter.Eq(s => s, "triangle"));

// Version 2 succeeds in finding a match
var elemMatchFilter_v2 = Builders.Filter.ElemMatch(
x => x.MyStringArray,
s => s == "triangle"));

var filtersAnded = Builders.Filter.And(idFilter, elemMatchFilter_v2); // elemMatchFilter_v1 does NOT match
var update = Builders.Update.Set("MyStringArray.$", "rectangle");
var result = collection.UpdateOne(filtersAnded, update);
Ниже приведены выходные данные журнала, полученные из вызова UpdateOne() приведенного выше кода.

Код: Выделить всё

// Version 1 Serilog output
Command started update UpdateArraysTesting { "update" : "Samples", "ordered" : true, "$db" : "UpdateArraysTesting", "lsid" : { "id" : { "$binary" : { "base64" : "i6evdcuCQ+WC3dq0TBO2qw==", "subType" : "04" } } }, "updates" : [{ "q" : { "_id" : { "$oid" : "000000000000000000001002" }, "MyStringArray" : { "$elemMatch" : { "@" : "triangle" } } }, "u" : { "$set" : { "MyStringArray.$" : "rectangle" } } }] }
Command succeeded update UpdateArraysTesting 0.8399 { "n" : 0, "nModified" : 0, "ok" : 1.0 }

// Version 2 Serilog output
Command started update UpdateArraysTesting { "update" : "Samples", "ordered" : true, "$db" : "UpdateArraysTesting", "lsid" : { "id" : { "$binary" : { "base64" : "p9PIap2yRKqvqtBjRKFa+Q==", "subType" : "04" } } }, "updates" : [{ "q" : { "_id" : { "$oid" : "000000000000000000001002" }, "MyStringArray" : { "$elemMatch" : { "$eq" : "triangle" } } }, "u" : { "$set" : { "MyStringArray.$" : "rectangle" } } }] }
Command succeeded update UpdateArraysTesting 0.7627 { "n" : 1, "nModified" : 1, "ok" : 1.0 }
Репозиторий GitHub

Вернуться в «C#»