2009-10-07 9 views
15

Mam dwa zestawy indeksów wyszukiwania. TestIndex (używany w naszym środowisku testowym) i ProdIndex (używane w środowisku PRODUKCJI). Lucene zapytanie do wyszukania: + data: [20090410184806 DO 20091007184806] działa poprawnie dla indeksu testowego, ale podaje ten komunikat o błędzie dla indeksu Prod.Potrzebna pomoc w ustaleniu przyczyny dla maxClauseCount jest ustawiona na 1024 błąd

„maxClauseCount jest ustawiony na 1024”

Jeśli mogę wykonać następującą linię tuż przed wykonaniem zapytania, to ja nie rozumiem tego błędu. BooleanQuery.SetMaxClauseCount (Int16.MaxValue); searcher.Search (myQuery, collector);

Brak tu czegoś? Dlaczego ten błąd nie występuje w indeksie testu? Schemat dla dwóch indeksów jest taki sam. Różnią się tylko od liczby rekordów/danych. Indeks SPRO ma większą liczbę rekordów (około 1300) niż te z testu (około 950).

Dzięki za przeczytanie.

+0

chk http://wiki.apache.org/lucene-java/LuceneFAQ#Why_am_I_getting_a_TooManyClauses_exception.3F – Narayan

Odpowiedz

11

Zapytanie dotyczące zakresu zostaje zasadniczo przekształcone w zapytanie boolowskie z jedną klauzulą ​​dla każdej możliwej wartości, połączone OR.

Na przykład cena + zapytanie [10 do 13] jest przekształcona do logicznej zapytania

+(price:10 price:11 price:12 price:13) 

założeniu, że wszystkie wartości 10-13 występują w indeksie.

Przypuszczam, że wszystkie 1300 wartości mieszczą się w podanym zakresie. Tak więc zapytanie boolowskie ma 1300 klauzul, które są wyższe niż domyślna wartość 1024. W indeksie testowym limit 1024 nie został osiągnięty, ponieważ istnieje tylko 950 wartości.

+0

Dziękuję Shashikant za odpowiedź. Jakie jest rozwiązanie tego problemu? BooleanQuery.SetMaxClauseCount (Int16.MaxValue); to ponoć bardzo kosztowna rozmowa. Dzięki. –

+1

Minusem jest obniżona wydajność zapytania z liczbą niepowtarzalnych znaczników czasu. Ale nie jest tak źle. Możesz go wypróbować i sprawdzić, czy perfromancja jest akceptowalna. Powinieneś być w porządku. Lucene 2,9 (Java) znacznie poprawił zakres zapytań. Nie jestem pewien, kiedy to zostanie przeniesione do wersji .Net. W międzyczasie istnieją inne sztuczki, których można używać w przypadku zapytań dotyczących dat. Zazwyczaj obejmuje to datę zerwania na rok, miesiąc i dzień.To wymaga wiele pracy, aby przetłumaczyć zapytanie użytkownika do leżącego u podstaw formatu luceńskiego. Spróbuj wyszukać "lucene date query", aby uzyskać interesujące pomysły. –

+0

W międzyczasie możesz inaczej zaprojektować swoje pole daty - czy możesz ograniczyć je do dni w ciągu jednego roku? (ograniczając go do 365 wartości)? Lub podzielić dane na rok, miesiąc i dzień i użyć bardziej złożonego zapytania? Wiem, że jest to nieeleganckie, ale może działać. –

12

Miałem ten sam problem. Moim rozwiązaniem było złapanie BooleanQuery.TooManyClauses i dynamiczne zwiększenie maxClauseCount.

Oto kod, który jest podobny do tego, co mam w produkcji.

Good Luck, Randy


    private static Hits searchIndex(Searcher searcher, Query query) 
     throws IOException 
    { 
     boolean retry = true; 
     while (retry) 
     { 
      try 
      { 
       retry = false; 
       Hits myHits = searcher.search(query); 
       return myHits; 
      } 
      catch (BooleanQuery.TooManyClauses e) 
      { 
       // Double the number of boolean queries allowed. 
       // The default is in org.apache.lucene.search.BooleanQuery and is 1024. 
       String defaultQueries = Integer.toString(BooleanQuery.getMaxClauseCount()); 
       int oldQueries = Integer.parseInt(System.getProperty("org.apache.lucene.maxClauseCount", defaultQueries)); 
       int newQueries = oldQueries * 2; 
       log.error("Too many hits for query: " + oldQueries + ". Increasing to " + newQueries, e); 
       System.setProperty("org.apache.lucene.maxClauseCount", Integer.toString(newQueries)); 
       BooleanQuery.setMaxClauseCount(newQueries); 
       retry = true; 
      } 
     } 
    } 
+0

To jest dobre rozwiązanie, ale dlaczego wcześniej nie policzyć klauzul i ustawić je poprawnie zamiast po złapać wyjątek? Czy wpłynie to na wydajność, jeśli przetwarzana jest duża ilość danych? – trillions

+1

Nanshi, powodem jest to, że nie można * obliczać. Nie ma sposobu, aby dowiedzieć się, ile elementów znajduje się w zakresie, dopóki * po * nie wykonasz zapytania, ale wtedy zapytanie to zostanie przekształcone w zapytanie Boolean, w którym wyjątek zostanie zgłoszony. –

+0

Dzięki Randy! Mam przypadek różnic, że sam zbudowałem zapytania Boolean, więc mogłem je liczyć przed uruchomieniem wyszukiwania. – trillions

1

Miałem ten sam problem w kod C# działa z systemem zarządzania treścią stron internetowych Sitecore. Użyłem odpowiedzi Randy'ego powyżej, ale nie mogłem użyć funkcji Pobierz i ustaw właściwości. Zamiast tego pobrałem bieżącą liczbę, zwiększyłem ją i odłożyłem. Pracował świetnie!

catch (BooleanQuery.TooManyClauses e) 
{ 
    // Increment the number of boolean queries allowed. 
    // The default is 1024. 
    var currMaxClause = BooleanQuery.GetMaxClauseCount(); 
    var newMaxClause = currMaxClause + 1024; 
    BooleanQuery.SetMaxClauseCount(newMaxClause); 
    retry = true; 
} 
0

Po prostu wstaw, BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE); i gotowe.

Powiązane problemy