2011-08-17 79 views
6

查詢子集由多個值,我使用RavenDB建立371,我有以下模型:在RavenDB

class Product { 
public string Id { get; set; } 
public ProductSpec[] Specs { get; set; } 
} 

class ProductSpec { 
public string Name { get; set; } 
public string Value { get; set; } 
} 

我希望能夠查詢其擁有一套規範的產品。當由單一規範查詢:

session.Query<Product>() 
.Where(product => product.Specs.Any(spec => spec.Name == "Color" && spec.Value == "Red")) 
.ToList(); 

預期的結果是返回,但是當一個額外的規範謂詞補充說:

不返回任何結果,即使第一個查詢返回的結果中包含規格名稱爲「國家」和規格值「美國」的產品。使用LuceneQuery方法時觀察到相同的結果。這似乎是與this discussion類似的問題,但我無法實現建議的解決方案。具體來說,創建建議的索引後,我不知道如何查詢它。

如何在RavenDB中支持這種類型的查詢?

編輯

我仍然無法在複合類型的集合多個值查詢。相反,我改變了模型,以便spec/value組合是一個連接的字符串,這樣specs集合就是一個字符串數組。這可以通過多個值來查詢:

class Product { 
public string Id { get; set; } 
public int CategoryId { get; set; } 
public string[] Specs { get; set; } 
} 

僅供參考,原始模型和查詢使用MongoDB他們multikeys指數功能時起作用。 MongoDB非常令人驚訝的問題是count()操作是slow for index queries。這種類型的查詢對分頁至關重要,雖然count可以被緩存,但我希望有一個解決方案可以提供這種開箱即用的功能。另外,我還有一個要求是能夠爲任意集合的產品聚合規範組(例如,獲得給定類別中產品的所有規格/值組合的集合)。在MongoDB中,這可以通過使用MapReduce功能來實現,但是MapReduce操作的結果是靜態的,並且必須在源數據更改時手動更新,而RavenDB在後臺自動更新MapReduce索引。因此,儘管在RavenDB中聲明MapReduce索引比在MongoDB IMO中更加繁瑣,但自動後臺更新遠遠超過了缺點。我會查看CouchDB,因爲它們的視圖也會自動更新,儘管看起來它們是按需更新的,而不是在後臺自動更新,不知道這是否會成爲問題。

+0

你可以看到討論如何在這裏解決此問題: http://groups.google.com/group/ravendb/browse_thread/thread/dd8a77ccf7322c00/ab97561899624c47 –

+0

我發現的建議解決方案適用於簡單類型(如字符串數組)的集合,但不適用於ProductSpec等複合類型。查詢最終沒有返回結果。 – eulerfx

回答

1

我已經改變了一下模型,並能夠使用AbstractIndexCreationTask中的Project方法實現所需的結果。這是(簡化)數據模型:

public class Product 
{ 
    public string Id { get; set; } 
    public int CategoryId { get; set; } 
    public int TotalSold { get; set; } 
    public Dictionary<string, string> Specs { get; set; } 
} 

這是該指數定義:

public class Products_ByCategoryIdAndSpecs_SortByTotalSold : AbstractIndexCreationTask<Product> 
{ 
    public Products_ByCategoryIdAndSpecs_SortByTotalSold() 
    { 
     this.Map = products => from product in products 
           select new 
           { 
            product.CategoryId, 
            _ = Project(product.Specs, spec => new Field("Spec_" + spec.Key, spec.Value, Field.Store.NO, Field.Index.ANALYZED)), 
            product.TotalSold 
           }; 
    } 
} 

然後我就可以查詢像這樣:

var results = session.Advanced.LuceneQuery<Product, Products_ByCategoryIdAndSpecs_SortByTotalSold>() 
     .WhereEquals("CategoryId", 15920) 
     .AndAlso().WhereEquals("Spec_Class", "3A") 
     .AndAlso().WhereEquals("Spec_Finish", "Plain") 
     .OrderBy("-TotalSold") 
     .ToList(); 

這將返回產品類別「銷售」規格值爲「3A」和「完成」規格值爲「普通」的「15920」按銷售總單位的降序排列。

關鍵是使用Project方法,該方法基本上爲Lucene文檔中的每個規格名稱 - 值對創建字段。

3

我嘗試過不同的事情,並且無法使其工作。您試圖執行的具體查詢由RavenDB(版本426)解析爲此Lucene查詢:

「{(Name:Color AND Value:Red)AND(Name:Country AND Value:US)}」which解釋你爲什麼沒有結果。

谷歌搜索關於這個問題之後,我發現這個職位:Lucene Query Syntax

不同的解決方法是答案之中建議。希望這會有所幫助。我自己雖然很好奇,但如果這是不可能的。