MongoDB C#驱动程序和带类型API的过滤位置运算符$[< identifier>]

hyrbngr7  于 2023-10-16  发布在  Go
关注(0)|答案(1)|浏览(96)

我有一个MongoDB集合,其中包含如下所示的文档:

{
    "Name" : "Name1",
    "AA" : [ 
        {
            "B" : {
                "Name" : "Name2"
            },
            "CC" : [ 
                {
                    "Field" : "Value"
                }
            ]
        }
    ]
}

我正在使用C#和2.7 MongoDB驱动程序。
我想把一个元素推到AA中那些符合特定条件的元素的CC数组中。我可以用下面的代码做到这一点:

[TestFixture]
class TestClass
{
    [Test]
    public void Test()
    {
        var b = new B { Name = "Name2" };
        var c = new C { Field = "Value2" };

        var field = new StringFieldDefinition<Document>("AA.$[element].CC");
        var updateDefinition = Builders<Document>
            .Update
            .Push(field, c);

        var arrayFilterBson = new BsonDocument("element.B",
            new BsonDocument("$eq", b.ToBsonDocument()));
        var arrayFilter = new BsonDocumentArrayFilterDefinition<AgentRecord>(arrayFilterBson);

        var documentFilter = Builders<Document>.Filter.Eq(r => r.Name, "Name1");

        var updateOptions = new UpdateOptions 
        { 
            IsUpsert = false,
            ArrayFilters = new ArrayFilterDefinition[] {  arrayFilter }
        };

        var settings = new MongoClientSettings
        {
            Server = new MongoServerAddress("localhost", 27000)
        };

        var mongoClient = new MongoClient(settings);
        var database = mongoClient.GetDatabase("so-question");
        var collection = database.GetCollection<Document>("collection");
        collection.UpdateOne(documentFilter, updateDefinition, updateOptions);
    }
}

// Mapping classes
public class Document
{
    public string Name { get; set; }
    public A[] AA { get; set; }
}

public class A
{
    public B B { get; set; }
    public C[] CC { get; set; }
}

public class B
{
    public string Name { get; set; }
}

public class C
{
    public string Field { get; set; }
}

是否有一种方法可以通过类型化的API来实现相同的功能,以避免在定义(如AA.$[element].CCelement.B)中硬编码字段的名称?

当然,我担心当类的属性的名称改变时,或者例如如果我使用[BsonElement("name")]属性来控制Map属性的名称时,必须更改这些硬编码的表达式。

jv2fixgn

jv2fixgn1#

我知道这已经很晚了,但如果其他人也像我一样寻找答案,请尝试Mongo的AllMatchingElements方法:
表示使用数组筛选器时数组中的所有匹配元素(对应于服务器的“$[identifier]”更新运算符)。
所以updateDefinition应该是

var updateDefinition = Builders<Document>.Update.Push(
    doc => doc.AA.AllMatchingElements("element").CC,
    c);

相关问题