使用 C# 代码从 MongoDB 数组中获取不同的值,它专门匹配某些值

Using C# code Get Distinct values from MongoDB array where it is matching some values specifically

我是 MongoDB 的新手。我有一个名为 Documents 的文档,其中有多个数据,如下所述

数据 1 -

{
    "ProjId": 18586,
    "ArtifactAttributes": [
        {
            
            "AttributeName": "Author",
            "AttributeValue": "XYZ"
            
        },
        {
            
            "AttributeName": "Address",
            "AttributeValue": "Addrr1"
            
        },
        {
            
            "AttributeName": "Owner",
            "AttributeValue": "manoj.naik"
            
        }
    ]
}

数据 2 -

{
    "ProjId": 18587,
    "ArtifactAttributes": [
        {
            
            "AttributeName": "Author",
            "AttributeValue": "ABC"
            
        },
        {
            
            "AttributeName": "Address",
            "AttributeValue": "Addrr2"
            
        },
        {
            
            "AttributeName": "Owner",
            "AttributeValue": "kumar.manoj"
            
        }
    ]
}

数据 - 3

{
    "ProjId": 18588,
    "ArtifactAttributes": [
        {
            
            "AttributeName": "Author",
            "AttributeValue": "PQR"
            
        },
        {
            
            "AttributeName": "Address",
            "AttributeValue": "Addrr3"
            
        },
        {
            
            "AttributeName": "Owner",
            "AttributeValue": "kumar.manoj"
            
        }
    ]
}

我想要 return 不同的值,其中 AttributeName 等于 Owner

预期结果 - [manoj.naik,kumar.manoj]

为此,我编写了如下代码,但它不是 returning 预期结果,而是 returning 来自 AttributeValue 的所有不同值,而不是 [=] 17=] 其中有 Owner

我得到的结果如下

[XYZ,Addrr1,manoj.naik,ABC,Addrr2,kumar.manoj,PQR,Addrr3]

我的 C# 代码 -

var ownerFilter = Builders<Documents>.Filter.ElemMatch(x => x.ArtifactAttributes, p => p.AttributeName.Equals("Owner"));
var ownerValueFieldDefinition = new StringFieldDefinition<Documents, string>("ArtifactAttributes.AttributeValue");
var distinctItems = _projectArtifacts.Distinct(ownerValueFieldDefinition, ownerFilter).ToList();

它不起作用,因为 ElemMatch 匹配任何在其 ArtifactAttributes 中包含 AttributeName == "Owner" 元素的文档。它 returns 未经修改的原始文档,它不会神奇地删除您不需要的 ArtifactAttributes 值。

据我所知,没有优雅的方法可以做你想做的事,但你可以这样做:

var distinctItems = _projectArtifacts
    .Aggregate()
    .Unwind(x => x.ArtifactAttributes)
    .Match(x => x["ArtifactAttributes.AttributeName"] == "Owner")
    .Group("{ _id: '$ArtifactAttributes.AttributeValue' }")
    .ToList()
    .Select(x => x["_id"].AsString)
    .ToList();

分步说明:

  1. Aggregate - 启动聚合管道。
  2. Unwind - 用副本替换每个文档,每个副本只包含 ArtifactAttributes.
  3. 的一个值
  4. Match - 过滤文档,只留下 AttributeName == "Owner".
  5. Group - 按 AttributeValue 对文档进行分组。这允许在 _id 字段中获取所有不同的值。
  6. ToList - 从数据库中获取结果。聚合总是 returns 文档列表,而不仅仅是值。因此,您必须执行更多步骤才能获取值列表。
  7. SelectToList - 使用 LINQ 获取值列表。