2012-03-30 9 views

Antwort

2

Das ist in RavenDB nicht möglich - das Feld, das Sie abfragen, muss sich links vom Prädikat befinden, und das Recht des Prädikats darf nicht auf ein anderes Feld verweisen.

Wie Sie dies umstrukturieren - Sorry, nicht sicher.

Edit:

Okay, es dauerte einige Experimente - aber ich schaffte es IF funktioniert es möglich ist, entweder Umstrukturierung MaterializedPath oder eine neue Eigenschaft hinzuzufügen. Ich nehme an, hier ist es eine neue Eigenschaft, um jede Verwirrung zu vermeiden.

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

Und hier läuft:

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)); 
    } 
} 

Die Ausgabe von dieser ist:

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

Hoffnung, das hilft.

Edit 2:

Der Konstruktor ich auf Artikel haben wie folgt aussieht, nur für einfache Tests:

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

Zusätzlich eine einzigartige Dokument-ID darstellen - warum nicht die Seiten Flip in diesem Prädikat. Es sollte das gleiche tun, oder habe ich etwas verpasst? –

+0

"A B C" beginnt mit "A B", "A B" beginnt nicht mit "A B C". –

+0

Ich höre dich, aber ich bin sicher, dass es einen Weg gibt, dies zu tun, da RavenDB auf Lucene basiert (Lucene ist eine Volltext-Suchmaschine, die das kann) ... Vielleicht mit etwas wie RavenDBs fortgeschrittener Lucene-Abfrage? – W3Max

1

I Vorgeschlagen werde einen Index erstellen, die jede der Möglichkeiten der Suche enthalten . Dieser wird viele Elemente in Ihrem Index erstellen, aber gleichzeitig ist es die Macht des Lucene schnell suchen

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

Es ist wichtig, dass „Weg“

+0

Sehr gute Antwort. Zuerst dachte ich, es könnte funktionieren, aber leider sind Tags ein bisschen anders als Bäume. – W3Max