c# - 如何使用 C# 在 MongoDb 中控制投影定义
问题描述
我有一个这样的域类。
public class Thing
{
public Guid Id { get; set; }
public string Name { get; set; }
public Dictionary<string, string> Stuff { get; set; }
}
我正在使用以下内容从我的数据库中检索它。
return await _db.Things
.Find(x => x.Name == name)
.SingleOrDefaultAsync(token);
正如我所注意到的,可能会有大量不必要的数据,所以我使用了这样的投影。
ProjectionDefinition<Thing> projection = Builders<Thing>
.Projection
.Include(a => a.Id)
.Include(a => a.Name);
BsonDocument projected = await _dbContext.Things
.Find(x => x.Name == name)
.Project(projection)
.SingleOrDefaultAsync(token);
这可行,但自然会削减所有字典内容。我想更改投影的定义以包括该字段,但对构成元素进行过滤。假设我只想引入以鸭子开头的所述字典的键。尝试可能是这样的。
ProjectionDefinition<Thing> projection = Builders<Thing>
.Projection
.Include(a => a.Id)
.Include(a => a.Name)
.Include(a => a.Stuff.Where(b => b.Key.StartsWith("duck")));
这导致异常如下。
System.NotSupportedException:不支持表达式树:{document}{configuration}
鉴于我对 MongoDb 的无知,我不知道是否应该添加某些内容、删除某些内容或完全忘记这个想法。我还尝试使用原始类型以能够以这种方式过滤内容,但我得到的唯一解决方案是后取,基本上是对检索到的数据进行处理。我想降低从数据库到我的服务的有效负载。
Thing projected = await _dbContext.Things
.Find(x => x.Name == name)
.Project<Thing>(projection)
.SingleOrDefaultAsync(token);
它是否可行,如果可行,如何(或至少谷歌搜索)?
努力证明:代码示例、一般操作、教程、错误答案等。它可能在某个地方,但我没能找到它(或者如果找到了就认出来)。
最后,我陷入了以下境地——上帝原谅我,因为我不知道自己在做什么。这是完全正确的方向还是一群疯狂的驴子会为此咬我的下背部?!
ProjectionDefinition<Thing, Thing> wtf = Builders<Thing>.Projection
.Expression(a => new Thing
{
Id = a.Id,
Name = a.Name,
Stuff = a.Stuff
.Where(b => b.Key == scope)
.ToDictionary(b => scope, b => b.Value)
});
解决方案
这是一个mongo
使用 MongoDB v4.2.8 的 shell 查询。
考虑这个输入文档:
{
"_id" : 1,
"name" : "john",
"stuff" : {
"mycolor" : "red",
"fruit" : "apple",
"mybook" : "programming gems",
"movie" : "star wars"
}
}
目标是投影name
和stuff
字段,但stuff
只有以 . 开头的字段名称"my"
。
聚合查询:
db.test.aggregate([
{
$project: {
_id: 0,
name: 1,
stuff: {
$filter: {
input: { $objectToArray: "$stuff" },
as: "stf",
cond: { $regexMatch: { input: "$$stf.k" , regex: "^my" } }
}
}
}
},
{
$addFields: { stuff: { $arrayToObject: "$stuff" } }
}
])
并且,预计的输出:
{
"name" : "john",
"stuff" : {
"mycolor" : "red",
"mybook" : "programming gems"
}
}
推荐阅读
- sql - Postgres - 用户定义的订单序列
- ajax - 如何在附加jquery代码相同的laravel图像中动态图像
- php - 有条件地在 woocommerce 产品页面上显示变体描述
- express-gateway - 在 Express Gateway 中,如何停止添加斜杠的代理端点
- google-analytics - 从 Google Analytics Data API (GA4) 获取基于多个指标
- airflow - Airflow - 在通过 TriggerDagRunOperator 发送之前设置 dag_run conf 值
- django - 在 Django 表单中查找小部件的选定值
- java - 运行 Quarkus 生产 Jar 时出错
- c++ - 在 C++ 中寻找更好的条件继承方法
- c# - 如何使用位图或图像一次读取一行图像像素