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