2009-10-12 7 views
5

Mam indeks Lucene, który zawiera dokumenty, które mają pole "typ", to pole może być jedną z trzech wartości "artykuł", "forum" lub " blog ". Chcę, aby użytkownik mógł wyszukiwać w tych typach (jest pole wyboru dla każdego typu dokumentu)Zapytanie Lucene - "Dopasuj dokładnie jeden z X, Y, Z"

Jak utworzyć zapytanie Lucene w zależności od typów wybranych przez użytkownika?

Kilka warunków są:

  • Jeżeli użytkownik nie wybiera jeden z typów, chcę nie wyniki tego typu.
  • Na uporządkowanie wyników nie powinno wpływać ograniczenie pola typu.

Dla porównania, gdybym miał napisać to w SQL (na „blogu lub forum szukaj”) bym napisać:

SELECT * FROM Docs 
WHERE [type] in ('blog', 'forum') 

Odpowiedz

4

Dla porównania, gdyby ktoś jeszcze natknąć się ten problem, tu jest moje rozwiązanie:

IList<string> ALL_TYPES = new[] { "article", "blog", "forum" }; 
string q = ...; // The user's search string 
IList<string> includeTypes = ...; // List of types to include 
Query searchQuery = parser.Parse(q); 
Query parentQuery = new BooleanQuery(); 
parentQuery.Add(searchQuery, BooleanClause.Occur.SHOULD); 
// Invert the logic, exclude the other types 
foreach (var type in ALL_TYPES.Except(includeTypes)) 
{ 
    query.Add(
     new TermQuery(new Term("type", type)), 
     BooleanClause.Occur.MUST_NOT 
    ); 
} 
searchQuery = parentQuery; 

I odwrócony logikę (tj wykluczone typy użytkownik nie zaznaczona), bo jeśli nie robić uporządkowanie wyników zostaje utracone. Nie jestem pewien dlaczego ...! To wstyd, ponieważ sprawia, że ​​kod jest mniej czytelny/łatwy w utrzymaniu, ale przynajmniej działa!

3

Dodaj ograniczenia do odrzucenia dokumentów, które nie zostały wybrane. Na przykład, jeśli została zaznaczona tylko „artykuł”, ograniczenie byłoby

-(type:forum type:blog) 
+0

To jest to, co zrobiłem na końcu, chociaż użyłem API zamiast tworzyć go jako ciąg, zobacz moją odpowiedź, jeśli jesteś zainteresowany. – thatismatt

0

Choć sugestia Ericksona wydaje się w porządku, można użyć pozytywną presję ANDed z wyszukiwanym hasłem, takie jak text:foo AND type:article na razie tylko „wyrób” zostało sprawdzone, lub text:foo AND (type:article OR type:forum) dla sprawy sprawdzono zarówno "artykuł" i "forum".

+0

Intrygujące dwa zapytania "tekst: foo AND (type: article OR type: forum)" i "text: foo AND -type: blog" nie dają takich samych wyników, pierwsze zapytanie zwraca blogi najpierw, gdzie jako drugi zapytanie zachowuje kolejność (np. blogi i artykuły są mieszane). Każdy pomysł, dlaczego? – thatismatt

+0

Lucene nie ma operatora "AND". Posiada + (wymaga) i - (zakaz) operatorów. – erickson

+0

@erickson: Proszę się różnić: np. http://incubator.apache.org/lucene.net/docs/2.1/Lucene.Net.QueryParsers.QueryParser.AND_OPERATOR.html –

Powiązane problemy