2017-05-04 29 views
1

我有一個這樣的文件:MongoDB的C# - 。首先()謂詞未在投影工作

{ "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並找到第一個匹配在.Items陣列中的子代碼item2的值。然後我想將它們拼合成一個投影,這樣我就可以對子數組中的第一個匹配項進行排序(我在投影中稱其爲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

不要儲存數字作爲字符串。將數字存儲爲數字。 「5」大於「230000」,「10000000000」小於「230000」。 – Servy

+0

這只是爲了舉例說明我的問題。我會相應地更新問題。 – gplumb

回答

0

在查看MongoDB驅動程序源代碼時,我能夠確定.First()謂詞將正確觸發,它是使用結果項上的單個字段是問題(驅動程序似乎忽略了謂詞完全在這種情況下,這就是爲什麼它產生一個'0')。

要解決此限制,解決方案是投影.First()謂詞的整個結果(而不是所需的屬性),然後更改隨後的.OrderBy()子句以使用所需的屬性。

投影/分類代碼現在看起來是這樣的:

// 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();