Mongodb C# driver return only matching sub documents in array(Mongodb C# 驱动程序仅返回数组中匹配的子文档)
问题描述
我有一份这种格式的文件:
I have a document in this format:
{
_id: ...,
myArray: [{other: stuff}, {other: stuff}, ...],
...
}
我想从 myArray
中的子文档中找到匹配某些内容的元素,例如 _id
或字段值.
I want to find elements that match certain things, like the _id
or fields value from the sub-documents in myArray
.
我想返回文档,但使用过滤后的 MyArray
,其中仅存在匹配的子文档.
I want to return the documents, but with a filtered MyArray
where only the matching sub-documents are present.
我尝试做一个投影并包含这样的匹配元素:
I tried to do a projection and include the matched elements like this:
_mongoContext.myDocument
.Find(x => x.id == id & x.myArray.Any(y => myList.Contains(t.other)))
.Project<myModel>(Builders<myModel>.Projection.Include("myArray.$"))
我认为,这应该只返回 myArray
中匹配的第一个元素,而不是所有文档,这不是我想要的(我希望所有与查询匹配的子文档都存在在返回的文档中).
This, I think, should only return the first element that matched in myArray
instead of all documents, which is not what I want (I want all sub-documents that match the query to be present in the returned document).
无论如何它甚至都不起作用,我得到一个 positional projection does not match the query document
错误.也许是因为我没有使用 FindOne
?
And anyway it did not even work, I'm getting a positional projection does not match the query document
error. Maybe it's because I'm not using FindOne
?
无论如何,我怎样才能实现我正在寻找的东西?(见粗体问题)
In any case, how can I achieve what I'm looking for? (See question in bold)
推荐答案
通常你需要使用 $filter 过滤嵌套数组.但是,使用 MongoDB .NET 驱动程序和 IQueryable 接口可以更轻松地实现这一目标.
Typically you need to use $filter in Aggregation Framework to filter nested array. However there's an easier way to achieve that using MongoDB .NET Driver and IQueryable interface.
考虑最简单的模型:
public class MyModel
{
public string _id { get; set; }
public IEnumerable<MyNestedModel> myArray { get; set; }
}
public class MyNestedModel
{
public string other { get; set; }
}
以及以下数据:
var m = new MyModel()
{
_id = "1",
myArray = new List<MyNestedModel>() {
new MyNestedModel() { other = "stuff" },
new MyNestedModel() { other = "stuff" },
new MyNestedModel() { other = "stuff2" } }
};
Col.InsertOne(m);
您可以简单地在您的集合上调用 .AsQueryable()
,然后您可以编写 LINQ 查询,该查询将由 MongoDB 驱动程序转换为 $filter
,尝试:
you can simply call .AsQueryable()
on your collection and then you can write LINQ query which will be translated by MongoDB driver to $filter
, try:
var query = from doc in Col.AsQueryable()
where doc._id == "1"
select new MyModel()
{
_id = doc._id,
myArray = doc.myArray.Where(x => x.other == "stuff")
};
var result = query.ToList();
或者,您可以将 $filter
部分编写为原始字符串,然后使用 .Aggregate()
方法.使用这种方法,您不必映射"所有属性,但缺点是您失去了类型安全性,因为这只是一个字符串,请尝试:
Alternatively you can write $filter
part as a raw string and then use .Aggregate()
method. Using this approach you don't have to "map" all properties however the drawback is that you're losing type safety since this is just a string, try:
var addFields = BsonDocument.Parse("{ "$addFields": { myArray: { $filter: { input: "$myArray", as: "m", cond: { $eq: [ "$$m.other", "stuff" ] } } } } }");
var query = Col.Aggregate()
.Match(x => x._id == "1")
.AppendStage<MyModel>(addFields);
$addFields
用于覆盖现有字段.
这篇关于Mongodb C# 驱动程序仅返回数组中匹配的子文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Mongodb C# 驱动程序仅返回数组中匹配的子文档
基础教程推荐
- SSE 浮点算术是否可重现? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01