Pokazywanie postów oznaczonych etykietą sort. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą sort. Pokaż wszystkie posty

piątek, 27 września 2013

[FullTextSearch] ElasticSearch: Filtrowanie, Sortowanie, Paginacja

Filtrowanie

Filtrowanie zawęża zbiór dokumentów, na których odbywa się przeszukiwanie pełnotekstowe. Podejście takie znacznie poprawia wydajność zapytań. Filtr nie wpływa także na wynik wyszukiwania (pole _score) w zwracanej kolekcji wyników. Przykład poprawnego filtrowanego zapytania, gdzie kolekcja jest najpierw filtrowana, a później odpytana po indeksie:

POST http://localhost:9200/books/book/_search HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:9200
Content-Length: 160

{
 "query": {
  "filtered" : {
   "query" : {
    "field" : { "author" : "Kaku" }
   },
    "filter" : {
    "term" : { "year" : 1993 }
   }
  }
 }
}

Filtrować można także zawężając przeszukiwany zbiór

POST http://localhost:9200/books/book/_search HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:9200
Content-Length: 331

{
   "query":{
      "filtered":{
         "query":{
            "term":{
               "title":"worlds"
            }
         },
         "filter":{
            "range":{
               "year":{
                  "from":2000,
                  "to":2013
               }
            }
         }
      }
   }
}

Sortowanie

Ponieważ ElasticSearch może działać jako zwykła dokumentowa baza danych, musi także wspierać sortowanie zwracanych elementów. Wykorzystujemy do tego pole sort.

POST http://localhost:9200/books/book/_search HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:9200
Content-Length: 156

{
"query" : {
 "match" : {
  "author" : {
   "query" : "penrose kaku",
   "operator" : "or"
  }
 }
},
  "sort" : [
    { "price" : "asc" }
  ]
}

Paginacja

Stronnicowanie jest dziś powszechnie stosowaną techniką umożliwiającą przesyłanie danych małymi porcjami. Również ElasticSearch wspiera stronnicowanie za pomocą pól from oraz size. 

POST http://localhost:9200/books/book/_search HTTP/1.1
User-Agent: Fiddler
Content-Type: application/json
Host: localhost:9200
Content-Length: 184

{
"query" : {
 "match" : {
  "author" : {
   "query" : "penrose kaku",
   "operator" : "or"
  }
 }
},
  "sort" : [
    { "price" : "asc" }
  ],
 "from" : 2,
 "size" : 2
}

niedziela, 24 marca 2013

[NoSQL] MongoDB: Queries

Bazy NoSQL składują dane w postaci dokumentów JSON. Dokumenty takie odpytuje się przy użyciu zapytań specyficznych dla danej bazy danych. MongoDB udostępnia całkiem bogate API do efektywnego przeszukiwania dokumentów składowanych w kolekcjach. Zależnie od języka programowania z którego łączymy się z bazą, zapytania mogą być budowane w nieco odmienny sposób, ale koncepcja pozostaje ta sama. Poniżej kilka użytecznych przykładów na to jak pisać zapytania. Przykłady te nadają się do urchomienia z shella MongoDB (program mongo.exe), jednak na przykład w C# składnia jest bardzo podobna. Tym co różni connectory jest sposób rzutowania danych do danego języka programowania.

Podstawowymi funkcjami służącymi do budowania zapytań są find i findOne. Pierwsza zwraca wszystkie dokumenty spełniające dany warunek, natomiast findOne zwraca tylko pierwszy dokument spełniający ten warunek. Jako argument przekazuje się obiekt JavaScript zgodny z językiem zapytań. Dokumentacja MongoDB mówi, że find jest odpowiednikiem instrukcji SELECT z SQL, natomiast obiekt przekazywany jako parametr odpowiada instrukcji WHERE.

Wybieranie bezwarunkowe:

Nie podając warunku jako argument dla obu funkcji wybieramy wszystkie dokumenty, bądź pierwszy zaindeksowany.

db.users.find();
db.users.findOne();

Przeszukiwanie warunkowe:

Tutaj mamy sporo możliwości. Możemy żądać by dane property miało dokładnie jakąś wartość:

db.users.find({lastname: "Doe"});

Przeszukiwanie warunkowe wykonuje się za pomocą operatorów $lt i $gt (względnie $lte czy $gte).

var query = {};
query.lastname = "Doe";
query.age = { $gt :20};
db.users.find(query);

Podanie dwóch warunków powoduje, że oba muszą być spełnione, aby dokument został zwrócony.

Dokumenty zagnieżdżone:

Przy przeszukiwaniu zagnieżdżonych dokumentów, stosuje się notację z kropkami, tak jakbyśmy odczytywali zagnieżdżone property w JavaScripcie:

var query = {};
query["address.country"] = "USA";
db.users.find(query);

Projekcje:

Drugim, opcjonalnym argumentem dla zapytań jest obiekt, w którym możemy zadecydować, które pola nas interesują. Domyślnie zwrócone zostaną wszystkie pola dokumentu. Jeżeli chcemy któreś konkretne pola, pomijając inne, oznaczamy te pożądane wartością 1. Przy oznaczeniu pierwszego pola przez 1 zostanie zwrócone ono, oraz pola _id nadawane przez bazę. Aby je wyłączyć, możemy ustawić tą wartość na 0. Zatem aby zwrócić dokumenty z samymi imionami wystarczy:

db.users.find(query, {firstname:1, _id: 0});

Paginacja:

Stronnicowanie może być wykonywane bezpośrednio na bazie danych przy użyciu operatorów limit i take. 

db.users.find().limit(1).skip(1);

Sortowanie:
.
Podobnie jak paginacja wykonywane na wynikach jako kolejna funkcja w łańcuchu wywołań

db.users.find().sort({age: 1});

Wartość 1 oznacza sortowanie rosnąco, wartość -1 sortowanie malejąco.

sobota, 25 sierpnia 2012

[WPF] ICollectionView

WPF oferuje mechanizm wspierający podstawowe standardy dotyczące wyświetlania kolekcji, takie jak filtrowanie, sortowanie czy grupowanie. Mechanizm jest następujący : w momencie, gdy następuje data binding do obiektu typu IEnumerable, tworzony jest pomiędzy źródłem a celem tworzony jest niejawnie widok. Jest nim obiekt implementujący interfejs ICollectionView. Wspiera on wspomniane wcześniej operacje.
  • Sortowanie
Tworzymy obiekt klasy SortDescription, gdzie jako parametry konstruktora podawane jest property, po którym ma się odbyć sortowanie, oraz kierunek (rosnąco lub malejąco).


var sort1 = new SortDescription("Surname", ListSortDirection.Descending);   
c1.Items.SortDescriptions.Add(sort1);

  • Grupowanie
Aby móc w pełni wykorzystać grupowanie, należy nieco rozszerzyć wygląd ListBoxa o to, jak prezentowany będzie nagłówek grupowania.

<ListBox.GroupStyle>
    <GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Label Content="Age = " />
                    <Label Content="{Binding}"/>
                </StackPanel>                                
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListBox.GroupStyle>

Po dodaniu wyglądu nagłówka, można przejść do dodania mechanizmu grupującego. Najbardziej przydatne wydaje się być grupowanie po property.


var group1 = new PropertyGroupDescription("Age");
c2.Items.GroupDescriptions.Add(group1);

  • Filtrowaanie
 Aby móc filtrować kolekcję należy stworzyć delegata zwracającego wartość logiczną.


c3.Items.Filter = o =>
                        {
                            var p = o as Person;
                            if (p == null)
                                return false;
                            return p.Age > 27;
                        };