我有一个名为some_collection
的集合。为some_collection
的模式是这样的:(该模式通过C#DTO决定)为不同类型的嵌套文档制作动态构建器过滤器 - MongoDB C#驱动程序
{
_id: ObjectId(.....),
firstName: "fName",
lastName: "lName",
someType: 4,
innerObject: {
// see below
}
}
在我的C#代码,innerObject是一个抽象类,并有多个孩子的类。这些子类具有不同的属性,因此MongoDB集合中的文档不完全相同。他们所属的子类的类型由个人some_collection
文档中的someType
字段划定。所以,有2种不同类型的嵌套文档的audit_collection
的2个文件的例子:
{
_id: ObjectId('first'),
firstName: "Jane",
lastName: "Smith",
someType: 0,
innerObject: {
prop1: "foo",
prop2: "bar",
aCollectionOfStrings: ["a", "b", "c"] // this is what I wanna search
}
},
{
_id: ObjectId('second'),
firstName: "John",
lastName: "Doe",
someType: 3,
innerObject: {
prop1: "baz",
prop2: "foobarbaz",
aCollectionOfObjects: [
{
myProp: "hello", // this is what I want to search
irrelevantProp: "blah"
},
{
myProp: "hello5", // this is what I want to search
irrelevantProp: "blah"
},
{
myProp: "hello1", // this is what I want to search
irrelevantProp: "blah"
}
]
}
}
的应用案例这个问题,我想搜索用户提供的字符串,这样就可以在存在firstname
和lastname
属性(它位于文档的顶层,所有文档都很容易分享),以及对象的一些内部属性(因为嵌套的内部文档在模式上不同,所以它是更难做到)。因此,例如:
对于someType == 0
,我会寻找myDocument.innerObject.aCollectionOfStrings
,而与someType == 3
,我搜索每个myDocument.innerObject.aCollectionOfObjects
的myProp
财产。
在我的C#代码,如果我拉的全收集,然后用它LINQ操作,我有决定如何搜索完整的文档一个C#函数(基本上它检查的someType
的值,然后基于此,它知道要搜索的属性)以及它的嵌套文档,并且可以在C#代码中进行过滤。
然而,重构用建设者的过滤器后,我无法通过,C#语言过滤功能进入过滤器(很明显,因为所有的生成器正在做的是建立一个MongoDB的查询,我认为):
filter = filter & Builders<MyOwnType>.Filter.Eq(a => CheckIfObjectHasString(a, search), true);
凡CheckIfObjectHasString
是一样的东西:
private bool CheckIfObjectHasString(MyOwnType doc, string search)
{
if(doc.someType == 0)
{
return doc.innerObject.aCollectionOfStrings.Where(s => s.ToLower().Contains(search)).Any();
} else if(doc.someType == 3) {
return doc.innerObject.aCollectionOfObjects.Where(d => d.myProp.ToLower().Contains(search)).Any();
} else if(...)
{
// etc.
}
}
一个解决这个我想到了文件插入时也许是,在最顶层上创建some_collection
文件属性,T帽子拥有所有可搜索的材料,但这似乎是不洁的。我如何构建像上面这样的过滤器,而不是在LINQ或我刚刚提到的解决方案中进行处理?