如何解决如何使用 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);
这行得通,但自然而然地会剪切所有字典内容。我想改变投影的定义以包括该领域,但对构成元素进行过滤。假设我只想引入以 duck 开头的所述字典的键。尝试可能是这样的。
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 的无知,我不知道是否应该添加、删除或忘记这个想法。我还尝试使用原始类型以这种方式过滤内容,但我唯一的解决方案是 post-fetch,基本上是对检索到的数据进行处理。我想将负载从数据库降低到我的服务。
Thing projected = await _dbContext.Things
.Find(x => x.Name == name)
.Project<Thing>(projection)
.SingleOrDefaultAsync(token);
它是否可行,如果可行,如何(或至少要搜索什么)?
努力证明:code examples、general operations、tutorials、wrong answers 等。它可能在某处,但我没有找到它(或者如果找到了就认出来) .
最后,我进入了以下内容 - 上帝原谅我,因为我不知道自己在做什么。这完全是在正确的方向,还是一群疯狂的驴会为此咬我的下背部?!
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)
});
解决方法
这是使用 MongoDB v4.2.8 的 mongo
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","mybook" : "programming gems"
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。