我有这样的文件:
{
"parent1" : "foo",
"parent2" : "bar",
"parent3" : "ignore",
"parent4" : "ignore",
"Items": [{
"numbers": [
"item1" : "abc",
"item2" : 123457,
"item3" : "def"
]
}, {
"numbers": [
"item1" : "abc",
"item2" : 234568,
"item3" : "def",
]
}, {
"numbers": [
"item1" : "abc",
"item2" : 999998,
"item3" : "def"
]
}]
}
我希望能够对字段.parent1
,.parent2
进行查询,并在item2
数组中找到子.Items
的第一个匹配值。然后我想把它们展平成一个投影,这样我就可以对子数组中的第一个匹配项进行排序(我在投影中称之为Instance
)。
因此,对于> = 230000的搜索值,结果匹配将如下所示:
{
"Parent1": "foo",
"Parent2": "bar",
"Instance": "234567"
}
在使用LINQ和C#MongoDB驱动程序(asp.net核心)时,我试过这样的事情:
// Query stage (Works)
var query = collection.ToQueryable<T>().Where(x => x.parent1 == "foo" &&
&& x.parent2 == "bar" && x.Items.Any(y => y.numbers.item2 >= 230000));
// Projection (Doesn't work)
var projection = query.AsQueryable().Select(x => new Output()
{
Parent1 = x.parent1,
Parent2 = x.parent2,
Instance = x.Items.First(y => y.numbers.item2 >= 230000).item2,
});
// Sort and get results (Would work if the projection above did)
var result = projection.OrderBy(x => x.Instance).ToList();
我遇到的问题是First
谓词在投影中被忽略,因此返回的值为0
,导致排序阶段无用(并给我不好的结果)。
是否有另一种方法可以在LINQ中实现相同的功能,或者有一种方法可以使用C#MongoDB Builder对象实现这一目标吗?
答案 0 :(得分:0)
在查看MongoDB驱动程序源时,我能够确定.First()谓词是否会正确触发,它是在结果项上使用单个字段的问题(驱动程序出现在这种情况下完全省略谓词,这就是为什么它会产生一个&#39; 0&#39;)。
要解决此限制,解决方案是投影.First()谓词的整个结果(而不仅仅是所需的属性),然后更改后续的.OrderBy()子句以改为使用所需的属性。 / p>
投影/排序代码现在看起来像这样:
// Projection (Yield the whole object, not just a property from it)
var projection = query.AsQueryable().Select(x => new Output()
{
Parent1 = x.parent1,
Parent2 = x.parent2,
Instance = x.Items.First(y => y.numbers.item2 >= 230000)
});
// Sort and get results (Now just sort on the property we care about)
var result = projection.OrderBy(x => x.Instance.item2).ToList();