Die Suche nach Teilzeichenfolgen in RavenDB
Habe ich eine Reihe von Objekten des Typs Idea
public class Idea
{
public string Title { get; set; }
public string Body { get; set; }
}
Will ich Suche diese Objekte von substring. Zum Beispiel, wenn ich ein Objekt der Titel "Idee", will ich es gefunden, wenn ich geben Sie einen beliebigen Teilstring "Idee": i, - id, - ide, Idee, d, de, dea, e, ea, ein.
Ich bin mit RavenDB für die Speicherung von Daten. Die Suchanfrage wie folgt Aussehen:
var ideas = session
.Query<IdeaByBodyOrTitle.IdeaSearchResult, IdeaByBodyOrTitle>()
.Where(x => x.Query.Contains(query))
.As<Idea>()
.ToList();
während der index ist folgende:
public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea, IdeaByBodyOrTitle.IdeaSearchResult>
{
public class IdeaSearchResult
{
public string Query;
public Idea Idea;
}
public IdeaByBodyOrTitle()
{
Map = ideas => from idea in ideas
select new
{
Query = new object[] { idea.Title.SplitSubstrings().Concat(idea.Body.SplitSubstrings()).Distinct().ToArray() },
idea
};
Indexes.Add(x => x.Query, FieldIndexing.Analyzed);
}
}
SplitSubstrings()
ist eine Erweiterung Methode gibt alle unterschiedlichen substrings des gegebenen Strings:
static class StringExtensions
{
public static string[] SplitSubstrings(this string s)
{
s = s ?? string.Empty;
List<string> substrings = new List<string>();
for (int i = 0; i < s.Length; i++)
{
for (int j = 1; j <= s.Length - i; j++)
{
substrings.Add(s.Substring(i, j));
}
}
return substrings.Select(x => x.Trim()).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToArray();
}
}
Ist dies nicht funktioniert. Vor allem, weil RavenDB ist nicht zu erkennen SplitSubstrings()
Methode, weil es ist in meiner benutzerdefinierten assembly. Wie diese Arbeit zu machen, im Grunde, wie zu zwingen, RavenDB zu erkennen, diese Methode ? Außerdem ist mein Ansatz für diese Art der Suche (Suche von Teilstring) ?
BEARBEITEN
Im Grunde, das ich bauen will auto-complete-Funktion auf dieser Suche, so müssen Sie schnell sein.
Btw: ich bin mit RavenDB - Build #960
- RavenDB Indizes auf dem server ausgeführt, und daher haben Sie nicht den Zugriff auf benutzerdefinierte code wie. Der index, den Sie schreiben, wird in einen string umgewandelt, die an den server gesendet und kompiliert drüben, die StringExtension code nicht mit ihm zu gehen, daher der Fehler.
- Ich weiß, dass dies ist der server der Seite die Verantwortung, aber gibt es eine Möglichkeit, um zu injizieren, da meine benutzerdefinierten code ? Vielleicht mit Hilfe von Reflexion ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie durchführen substring-Suche über mehrere Felder mit dem folgenden Ansatz:
( 1 )
auf diese Website Sie können überprüfen, dass:
So standardmäßig, wenn Sie den index überprüfen Bedingungen in der Rabe-client, es sieht folgt aus:
Basierend auf, die, wildcard-Abfrage konstruiert werden kann:
die dann mit der
.In
und.Where
Konstruktionen (mit ODER Betreiber innen):( 2 )
Alternativ können Sie die Verwendung der reinen lucene-Abfrage:
( 3 )
Können Sie auch
.Search
Ausdruck, aber Sie bauen Ihre index sich anders, wenn Sie wollen, Suche über mehrere Felder:Zusammenfassung:
Auch im Hinterkopf haben, dass
*term*
ist eher teuer, vor allem die führenden Platzhalter. In diesem post finden Sie mehr info über es. Es wird gesagt, dass die führenden wildcard-Kräfte lucene führen Sie einen vollständigen scan auf dem index und kann somit drastisch verlangsamen Abfrage-performance. Lucene speichert intern die Indizes (tatsächlich sind die Begriffe von string-Feldern) alphabetisch sortiert und "liest" von Links nach rechts. Das ist der Grund, warum es schnell zu tun, eine Suche nach einem nachgestellten Platzhalterzeichen und langsam für eine führende eins.Also alternativ
x.Title.StartsWith("something")
verwendet werden können, aber dies natürlich nicht für die Suche in allen Teilstrings. Wenn Sie schnelle Suche, können Sie die option Index für die Felder, die Sie suchen möchten, um Analysiert zu werden, aber es wird wieder nicht für die Suche in allen Teilstrings.Wenn es ein die Leertaste innerhalb der substring-Abfrage, bitte überprüfen Sie diese Frage für eine mögliche Lösung.
Für die Vorschläge prüfen http://architects.dzone.com/articles/how-do-suggestions-ravendb.
Dies ist offenbar ein Duplikat von RavenDB schnell substring-Suche
Die Antwort gibt, die hier noch nicht genannt wurde, ist die Verwendung eines benutzerdefinierten Lucene analyzer genannt NGram
Incase jemand anderes kommt über diese. Raven 3 hat eine die
Search()
Erweiterung Methode, die es erlaubt für die substring-Suche.Ein paar Fallstricke:
Search()
war das direkt HinzugefügtQuery()
(d.h. ohneWhere()
,OrderBy()
etc dazwischen)Hoffe, das spart jemand einige frustration.
Habe ich es geschafft, dies zu tun im Speicher mit dem folgenden code:
Dies ersparte mir die Mühe, RavenDB Art der Suche für die Saiten mit den Contains-Methode, wie beschrieben, durch Daniel Lang ' s post.
Den
Contains
- Erweiterung die Methode ist diese: