问题描述
使用C#SDK查询MongoDB时,我希望能够投影为另一种类型.
I want to be able to project to another type when querying MongoDB using the C# SDK.
例如,下面我想使用构建器过滤器(或LINQ表达式)查询 MyType
,的集合,但我想将结果投影到 MySubType
.
For example, below I want to query the collection using builder filters (or LINQ expressions) for MyType
, but I want to project the result to MySubType
.
var mySubTypes = Database
.GetCollection<MyType>("MyCollection")
.Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, documentId))
.ProjectTo<MySubType>() // Project to another type??
.ToList();
可以想象 MySubType
是 MyType
的子集,使用继承表示:
One could imagine MySubType
to be a subset of MyType
, represented using inheritance:
public class MyType : MySubType
{
[BsonElement("documents")]
public List<string> Documents { get; set; }
}
public class MySubType
{
[BsonElement("name")]
public string Name { get; set; }
}
我为什么要这样做?
因为 Documents
数组非常大,并且仅在数据库引擎内的查询(即过滤)期间使用.检索和序列化此阵列将是不必要的费用.
Because the Documents
array is very large and used purely during querying (i.e. to filter) within the database engine. Retrieving and serializing this array will be an unnecessary cost.
推荐答案
我已经找到了执行所需映射的方法:
I have found the way to execute mapping you want:
collection
.Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, new[] { "c" }))
.Project(Builders<MyType>.Projection.Exclude(c => c.Documents))
.As<MySubType>()
.ToList();
但是首先,您应该在忽略额外元素的情况下为您的SubType注册映射.我不明白它是100%,似乎是驱动程序的错误,它没有从mongo获取 Documents
,但知道 MyType
具有这种属性.请注意,您应该先先注册类映射,然后再创建此类型的集合.
But first you should register mapping for your SubType with ignoring extra element. I don't understand it 100%, seems to be a bug of the driver, it doesn't get Documents
from mongo, but knows, that MyType
has such property. Note, you should register your class mapping, before you first create collection of this type.
if (!BsonClassMap.IsClassMapRegistered(typeof(MySubType)))
{
BsonClassMap.RegisterClassMap<MySubType>(cm =>
{
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
}
我是用示例数据完成的:
I did it with sample data :
var toInsert = new List<MyType>
{
new MyType {Id = 1, Name = "bla", Documents =new List<string> {"a", "b", "v"}},
new MyType {Id = 2, Name = "ada", Documents =new List<string> {"c", "d", "r"}},
};
并可以获得预期的输出:
And could get the expected output:
collection
.Find(Builders<MyType>.Filter.AnyIn(x => x.Documents, new[] { "c" }))
.Project(Builders<MyType>.Projection.Exclude(c => c.Documents))
.As<MySubType>()
.ToList()
.Dump();
这篇关于使用C#SDK投影到另一种类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!