2012-03-30 54 views

回答

2

你不能在RavenDB中做到這一點 - 你所查詢的字段必須在謂詞的左邊,謂詞的右邊不能引用另一個字段。

至於如何重組這個 - 對不起,不確定。

編輯:

好了,花了一些實驗 - 但我設法使它工作,如果有可能要麼重組MaterializedPath,或添加新的特性。我會在這裏假設這是一個新的屬性,以避免混淆。

// Sample class: 
public class Item 
{ 
    public string Name { get;set;} 
    public Dictionary<int, string> Path { get;set;} // Zero-based key on path. 
} 


// Query: Find nodes with path "A B" 
var query = session.Query<Item>().AsQueryable(); 
query = query.Where(item => item.Path[0] == "A"); 
query = query.Where(item => item.Path[1] == "B"); 

var found = query.ToList(); 

這裏,它正在運行:

IDocumentStore store = new EmbeddableDocumentStore { RunInMemory = true }; 
store.Initialize(); 

// Install Data 
using (var session = store.OpenSession()) 
{ 
    session.Store(new Item("Foo1", "A")); // NB: I have a constructor on Item which takes the path and splits it up. See below. 
    session.Store(new Item("Foo2", "A B")); 
    session.Store(new Item("Foo3", "A C D")); 
    session.Store(new Item("Foo4", "A B C D")); 
    session.Store(new Item("Foo5", "C B A")); 
    session.SaveChanges(); 
} 

using (var session = store.OpenSession()) 
{ 
    var query = session 
     .Query<Item>().AsQueryable(); 

    query = query.Where(item => item.Path[0] == "A"); 
    query = query.Where(item => item.Path[1] == "B"); 

    var found = query.ToList(); 

    Console.WriteLine("Found Items: {0}", found.Count); 

    foreach(var item in found) 
    { 
     Console.WriteLine("Item Name {0}, Path = {1}", item.Name, string.Join(" ", item.Path)); 
    } 
} 

的輸出是這樣的:

Found Items: 2 
Item Name Foo2, Path = [0, A] [1, B] 
Item Name Foo4, Path = [0, A] [1, B] [2, C] [3, D] 

希望有所幫助。

編輯2:

構造我對項目看起來是這樣的,只是爲了便於測試:

public Item(string name, string materializedPath) 
    { 
     Name = name; 
     var tmpPath = materializedPath.Split(' '); 
     Path = 
      tmpPath 
       .Zip(Enumerable.Range(0, tmpPath.Count()), (item, index) => new {Item = item, Index = index}) 
       .ToDictionary(k => k.Index, v => v.Item); 
    } 
+0

另外一點很重要 - 爲什麼不翻轉邊在這個謂詞中。它應該有效地做同樣的事情,還是我錯過了什麼? – 2012-03-30 07:45:37

+0

「A B C」以「A B」開頭,「A B」不以「A B C」開頭。 – 2012-03-30 09:11:23

+0

我聽說你,但我確信有一種方法可以做到這一點,因爲RavenDB是基於Lucene(Lucene是一個全文搜索引擎必須能夠做到這一點)......也許有像RavenDB高級Lucene查詢之類的東西? – W3Max 2012-03-30 13:02:51

1

我會建議建立一個包含每個搜索的可能性的指標。這將在您的索引創建的項目很多,但同時它的Lucene的力量,加快搜尋速度

Map = docs => from n in docs 
       let allPaths = n.MaterializedPath.Split(new char[]{' '}) 
       from path in allPaths 
       select new 
       { 
       Path = path 
       }; 

說,「路徑」表示唯一的文檔ID

+0

非常好的答案。起初我認爲它可以工作,但不幸的是,標籤與樹木有點不同。 – W3Max 2012-03-30 15:21:01