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

Posted

技术标签:

【中文标题】使用 C# 代码从 MongoDB 数组中获取不同的值,其中它专门匹配某些值【英文标题】:Using C# code Get Distinct values from MongoDB array where it is matching some values specifically 【发布时间】:2022-01-08 03:38:20 【问题描述】:

我是 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"
            
        
    ]

我想返回 AttributeName 等于 Owner 的不同值。

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

为此,我编写了如下代码,但它没有返回预期结果,而是返回来自AttributeValue 的所有不同值,而不是专门来自AttributeNameOwner

我得到的结果如下

[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();

【问题讨论】:

【参考方案1】:

它不起作用,因为ElemMatch 匹配任何在其ArtifactAttributes 中具有AttributeName == "Owner" 元素的文档。它返回原始未修改的文档,它不会神奇地删除您不需要的 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();

分步说明:

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

【讨论】:

谢谢。我试过 var ownerData = _projectArtifacts.Aggregate() .Unwind(doc => doc.ArtifactAttributes) .ReplaceRoot("$ArtifactAttributes") .Match(attr => attr.AttributeName.Equals("Owner") && attr. AttributeValue != null && attr.AttributeValue != "") .Project(b => new ArtifactAttributes AttributeValue = b.AttributeValue) .ToList(); var ownerList = ownerData.Select(x => x.AttributeValue).Distinct().Where(y => y != null).OrderBy(p => p).ToList();这个,它正在工作。 但是你的回答更可靠,所以我会同意的

以上是关于使用 C# 代码从 MongoDB 数组中获取不同的值,其中它专门匹配某些值的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 驱动程序以指定顺序从 MongoDB 获取文档 [重复]

MongoDB - 不能使用 .explain() 在 C# 代码中获取查询信息?

如何使用 LINQ 的 AsQueryable() 从 MongoDB 的内部数组中获取数据?

MongoDB - 获取具有不同的数组

如何从mongodb中的嵌套数组中获取值

mongodb在子文档数组的数组中获取不同的项目