2010-11-17 53 views
17

我有一個包含「tags」列表的文檔類。喜歡的東西:Linq查詢包含多個Contains/Any for RavenDB

class Item { 
    string Name { get; set; } 
    List<string> Tags {get; set;} 
} 

現在我想創造一個RavenDB查詢遞給我用的標籤列表過濾的所有項目。當使用實體框架,我設法通過這樣的事情要做到這一點:

var query = GetQueryable(); 
foreach (var tag in tags) 
{ 
    query = query.Where(i => i.Tags.Contains(tag)); 
} 

然而,這似乎並沒有與RavenDB工作,很可能是因爲含有不被支持。我也試着重寫它使用任何(Where(i => i.Tags.Any(t=>t == tag))),但給了我一個奇怪的例外:

Unable to cast object of type 
'System.Linq.Expressions.PrimitiveParameterExpression`1[System.String]' 
to type 'System.Linq.Expressions.MemberExpression 

任何偉大的想法?我完全錯了嗎?

+0

什麼是'GetQueryable()'返回類型?你在做什麼'query = query.Where(i => i.Tags.Contains(tag));'?什麼是查詢類型? – 2010-11-17 20:16:49

+0

GetQueryable()返回一個IQueryable 。我確實可以訪問整個DocumentSession,所以這只是一個例子。 – CodingInsomnia 2010-11-18 10:15:22

回答

18

包含確實尚不支持(或許是應該的,但這是另一回事完全 - 我們才真正添加支持各種運營商時,其要求)

作爲對任何多次查詢,我想你」重新嘗試做動態數據和要達到像

"X OR Y OR Z" 

這是一個很微妙的,並且默認的LINQ提供程序將聚合這些多個WHERE子句中使用AND,所以你的例子看起來像

"X AND Y AND Z" 

這顯然不會是這種情況。

您的這一個最好的選擇就是到了Lucene查詢(至少目前如此)下降,做這樣的事情:

var results = s.Advanced.LuceneQuery<Item>() 
        .Where(string.Format("Tags,:({0})", string.Join(" OR ", tags))); 

有意義嗎?上述

查詢將看起來像

"Tags,:(X OR Y OR Z)" 

注: 「標籤,」 通知RavenDB即標籤是一個數組

好吧,[編輯]!

,最簡單的辦法讓你真正想要什麼是沿着這些線路

   new IndexDefinition<Item, Item>() 
       { 
        Map = docs => from doc in docs 
            select new 
            { 
             Tags = doc.Tags 
            }, 
        Indexes = {{ x => x.Tags, FieldIndexing.Analyzed }} 
       }.ToIndexDefinition(store.Conventions)); 

然後查詢您的ANDS做一些事情,你可以做這樣的事情:

   var results = s.Advanced.LuceneQuery<Item, WhateverYouCalledThatIndex>() 
        .Where(string.Format("Tags:({0})", string.Join(" AND ", tags))); 

現在,要注意的事情

 Tags = doc.Tags 

Wi將整個數組序列化爲一個巨大的blob,因爲它只是可以用於這個例子的字符串。

我在看這表達更好的方法,這是不可能的,我們會想出這樣做的LINQ十歲上下的方式,因爲它並沒有真正跨地圖很好 - 但它的答案將工作:)

我想我會非常希望能夠至少做

Map = docs => from doc in docs 
            select new 
            { 
             Tags = String.Join(" ", doc.Tags) 
            }, 

(這是行不通的,所以不要嘗試),但它是一個有點更明確你想要達到的目標。

+0

關閉,但沒有雪茄! ;-)首先,我使用的版本似乎不適用於「Tags ,:」語法。但是,如果我使用名爲Name的單個屬性(並使用「Tags,Name:」)創建Tag類,那麼您的解決方案就可以工作。但它並不完全符合我的需要。我希望它只返回標籤列表中所有標籤(不包含任何標籤)中的所有標籤的項目。 – CodingInsomnia 2010-11-17 21:32:27

+0

好的,這是更困難的,你會如何做一個基於集合的關係數據庫操作?我認爲在這一點上,你可能實際上必須創建一個索引來將這些標籤合併到一個字段中,並指定你想要的分析器,並使用Lucene查詢來說「請求所有這些術語」 – 2010-11-18 12:37:45

+0

是的,它不是很漂亮在關係數據庫中,但我在這個問題中編寫的代碼實際上適用於實體框架。雖然並不漂亮,但幾乎沒有效率(這是我認爲Raven能夠做得更好的原因的一部分)。 – CodingInsomnia 2010-11-19 18:21:27