此查詢失敗(RavenDB 1.0.701)RavenDB StartsWith的LINQ(物化路徑)
var items= RavenSession.Query<Item>().Where(x => "161 193".StartsWith(x.MaterializedPath)).ToList();
有另一種方式?
在你問之前,我試圖讓父母(祖先)以materialized path (lineage column)得到一棵樹結構化的數據。
此查詢失敗(RavenDB 1.0.701)RavenDB StartsWith的LINQ(物化路徑)
var items= RavenSession.Query<Item>().Where(x => "161 193".StartsWith(x.MaterializedPath)).ToList();
有另一種方式?
在你問之前,我試圖讓父母(祖先)以materialized path (lineage column)得到一棵樹結構化的數據。
你不能在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);
}
我會建議建立一個包含每個搜索的可能性的指標。這將在您的索引創建的項目很多,但同時它的Lucene的力量,加快搜尋速度
Map = docs => from n in docs
let allPaths = n.MaterializedPath.Split(new char[]{' '})
from path in allPaths
select new
{
Path = path
};
說,「路徑」表示唯一的文檔ID
非常好的答案。起初我認爲它可以工作,但不幸的是,標籤與樹木有點不同。 – W3Max 2012-03-30 15:21:01
另外一點很重要 - 爲什麼不翻轉邊在這個謂詞中。它應該有效地做同樣的事情,還是我錯過了什麼? – 2012-03-30 07:45:37
「A B C」以「A B」開頭,「A B」不以「A B C」開頭。 – 2012-03-30 09:11:23
我聽說你,但我確信有一種方法可以做到這一點,因爲RavenDB是基於Lucene(Lucene是一個全文搜索引擎必須能夠做到這一點)......也許有像RavenDB高級Lucene查詢之類的東西? – W3Max 2012-03-30 13:02:51