2013-05-10 10 views
9

Jestem nowy w ElasticSearch i Couchbase. Buduję przykładową aplikację Java, aby dowiedzieć się więcej o ElasticSearch i Couchbase.ElasticSearch - Korzystanie z FilterBuilders

Czytanie ElasticSearch Java API, Filtry są lepiej stosowane w przypadkach, gdy sortowanie według wyniku nie jest konieczne i dla buforowania. ja wciąż nie zorientowali się, jak korzystać z FilterBuilders i mają następujące pytania:

  • Czy FilterBuilders być stosowany samodzielnie szukać?
  • Lub Czy zawsze muszą być używane z Query? (Jeśli to prawda, czy ktoś może podać przykład?)
  • Przechodząc przez dokumentację, jeśli chcę przeprowadzić wyszukiwanie w oparciu o wartości pól i chcę użyć FilterBuilders, jak mogę to zrobić? (Przy użyciu AndFilterBuilder lub TermFilterBuilder lub InFilterBuilder? Nie jestem jasne o różnicach między nimi.)

o 3 pytania, to faktycznie przetestowane z wyszukiwania za pomocą zapytań i stosując filtry, jak pokazano poniżej. Mam pusty wynik (bez wierszy), gdy próbowałem wyszukiwania przy użyciu FilterBuilders. Nie jestem pewien, co robię źle.

Dowolne przykłady będą pomocne. Miałem ciężki czas na przeglądanie dokumentacji, którą uważałem za rzadką, a nawet wyszukiwanie prowadziło do różnych niewiarygodnych forów użytkowników.

private void processQuery() { 
     SearchRequestBuilder srb = getSearchRequestBuilder(BUCKET); 
     QueryBuilder qb = QueryBuilders.fieldQuery("doc.address.state", "TX"); 
     srb.setQuery(qb); 

     SearchResponse resp = srb.execute().actionGet(); 
     System.out.println("response :" + resp); 
    } 

private void searchWithFilters(){ 
     SearchRequestBuilder srb = getSearchRequestBuilder(BUCKET); 
     srb.setFilter(FilterBuilders.termFilter("doc.address.state", "tx")); 
     //AndFilterBuilder andFb = FilterBuilders.andFilter(); 
     //andFb.add(FilterBuilders.termFilter("doc.address.state", "TX")); 
     //srb.setFilter(andFb); 
     SearchResponse resp = srb.execute().actionGet(); 
     System.out.println("response :" + resp); 
    } 

- -UPDATE--

Jak sugeruje odpowiedź, zmieniając na małe "TX" dzieła. Po rozwiązaniu tego pytania. Nadal mam następujące pytania:

  • W jakim scenariuszu (-ach) są używane filtry z zapytaniem? W jakim celu to będzie służyć?
  • Różnica między InFilter, TermFilter i MatchAllFilter. Pomocna będzie każda ilustracja.

Odpowiedz

11

Dobrze, należy użyć filtrów, aby wykluczyć, że dokumenty są brane pod uwagę podczas wykonywania zapytania. Filtry są szybsze, ponieważ nie wymagają żadnej punktacji i mogą być również buforowane.

To oczywiste, że musisz użyć filtru z search api, który wykonuje zapytanie i akceptuje opcjonalny filtr. Jeśli masz tylko filtr, możesz po prostu użyć zapytania match_all wraz z filtrem. Filtr może być prosty lub złożony, aby łączyć ze sobą wiele filtrów.

Jeśli chodzi o Java API, używane są nazwy dostępnych filtrów, bez większych różnic. Spójrz na przykład na this search example. W twoim kodzie nie widzę, gdzie wykonujesz setFilter na swoim obiekcie SearchRequestBuilder. Wydaje się także, że nie potrzebujesz filtrów i filtrów, ponieważ używasz jednego filtra. Ponadto może się zdarzyć, że indeksujesz przy użyciu domyślnych mapowań, a więc termin "TX" jest pisany małymi literami. Dlatego kiedy wyszukujesz używając terminu filtr, nie znajdziesz żadnego dopasowania. Spróbuj wyszukać "tx" pisane małymi literami.

Możesz zmienić swoje mapowanie, jeśli chcesz zachować termin "TX", tak jak podczas indeksowania, prawdopodobnie ustawiając pole jako not_analyzed, jeśli ma być tylko jeden token. W przeciwnym razie możesz zmienić filtr, możesz rzucić okiem na analizowane zapytanie, aby Twoje zapytanie zostało przeanalizowane w ten sam sposób, w jaki indeksowano treść.

Wystarczy popatrzeć na query DSL documentation uzyskać więcej informacji na temat zapytań i filtrów:

  • MatchAllFilter: Zapałki cały dokument, a nie że użyteczny powiedziałbym
  • TermFilter: Filtry do dokumentów zawierających pola, które zawierają termin (nie analizowano)
  • AndFilter Filtr związek stosowany do wprowadzenia i dwa lub więcej filtrów

Nie wiem, co masz na myśli przez InFilterBuilder, nie można znaleźć żadnego filtra o tej nazwie.

Zapytanie zazwyczaj zawiera to, co użytkownik wpisze przez pole wyszukiwania tekstu. Filtry są lepszym sposobem na zawężenie wyszukiwania, na przykład kliknięcie wpisów w aspektach. Dlatego wciąż masz zapytanie plus jeden lub więcej filtrów.

+0

Masz rację, ja edycji posta, aby ustawić filtr na searchrequestbuilder. i zmieniając na "tx" widzę wyniki! dzięki. Zmieniłem post, aby uwzględnić to i kilka pytań, które wciąż trwają ... dziękuję jeszcze raz. –

+0

Zaktualizowałem swoją odpowiedź zgodnie z zaktualizowanym pytaniem, sprawdź to. – javanna

+0

Spójrz na ten przykład wyszukiwania na przykład link jest zepsuty. –

6

Aby dołączyć do co @javanna powiedział:

sporo zamieszania mogą pochodzić z faktu, że filtry mogą być zdefiniowane na kilka sposobów:

Jaka jest różnica, o jaką możesz poprosić. I rzeczywiście możesz zbudować dokładnie tę samą logikę na dwa sposoby.

Różnica polega na tym, że zapytanie działa zarówno w zestawie wyników, jak i we wszystkich zdefiniowanych aspektach. Podczas gdy filtr (gdy jest zdefiniowany jako samodzielny) działa tylko na zestawie wyników, a NIE na dowolnych aspektach, które mógłbyś zdefiniować (wyjaśniono tutaj: http://www.elasticsearch.org/guide/reference/api/search/filter/)

2

Aby dodać do innych odpowiedzi, filtr InFilter jest używany tylko z FilterBuilders. Definicja to InFilter: Filtr dla pola na podstawie kilku terminów pasujących do dowolnego z nich.

Kwerendy Java API używa FilterBuilders, który jest fabryką dla konstruktorów filtrów, które mogą dynamicznie tworzyć zapytania z kodu Java. Robimy to za pomocą formularza i tworzymy naszą kwerendę na podstawie wyborów dokonywanych przez użytkownika za pomocą pól wyboru, opcji i list rozwijanych.

Oto Example code for FilterBuilders i jest to fragment z tego linku, który używa InFilter jak pokazano poniżej:

FilterBuilder filterBuilder; 
    User user = (User) auth.getPrincipal(); 
    if (user.getGroups() != null && !user.getGroups().isEmpty()) { 
     filterBuilder = FilterBuilders.boolFilter() 
       .should(FilterBuilders.nestedFilter("userRoles", FilterBuilders.termFilter("userRoles.key", auth.getName()))) 
       .should(FilterBuilders.nestedFilter("groupRoles", FilterBuilders.inFilter("groupRoles.key", user.getGroups().toArray()))); 
    } else { 
     filterBuilder = FilterBuilders.nestedFilter("userRoles", FilterBuilders.termFilter("userRoles.key", auth.getName())); 
    } 
    ...