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

sobota, 29 czerwca 2013

[Matlab] Operacje na wektorach i macierzach

Matlab jako jedno z najlepszych narzędzi do obliczeń inżynierskich oferuje sporo przydatnych funkcji do operacji na maciezach i wektorach. Oto niektóre z nich:
  • transpozycja (' lub funkcja transpose)
>> a = [1 2 3 4];
>> a'

ans =

     1
     2
     3
     4

>> transpose(a)

ans =

     1
     2
     3
     4
  • konkatenacja []
>> [a 1 2 3]

ans =

     1     2     3     4     1     2     3
  • podzbiór ()
>> a(2:3)

ans =

     2     3
  • linspace(elementy równomiernie rozłożone pomiędzy dwoma wartościami, pierwsze dwa argumenty to zakres, trzeci to ilość elementów)
>> linspace(0,5,6)

ans =

     0     1     2     3     4     5
  • suma kumulatywna (do każdego elementu dodawana jest suma poprzednich elementów)
>> cumsum(a)

ans =

     1     3     6    10
  • diff (różnica pomiędzy kolejnymi elementami, zwraca wektor o 1 element mniejszy od wektora wejściowego)
>> diff(a)

ans =

     1     1     1
  • podzbiór warunkowy
>> a(a>2)

ans =

     3     4
  • unique (zwraca posortowane unikatowe elementy)
>> unique([a 6 4 5])

ans =

     1     2     3     4     5     6
  • any (zwraca 0 lub jeden w zależności od tego, czy warunek jest spełniony)
>> any(a == 2)

ans =

     1

>> any(a == 0)

ans =

     0
  • find (zwraca indeksy spełniające dany warunek)
>> b = [4 3 0 1];
>> find (b==3)

ans =

     2
  • macierz jednostkowa
>> eye(3)

ans =

     1     0     0
     0     1     0
     0     0     1
  • transformacja macierz - wektor - operator (:)
>> g = eye(3);
>> g(:)

ans =

     1
     0
     0
     0
     1
     0
     0
     0
     1
  • wybór wiersza / kolumny
>> g(3,:)

ans =

     0     0     1

>> g(:,3)

ans =

     0
     0
     1

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.

niedziela, 17 marca 2013

[NoSQL] MongoDB + Node.js: mongoose

Interesującą konfiguracją dla aplikacji webowych jest Node.js jako serwer http udostępniający RESTowe API oraz MongoDB jako baza danych. Za takim pomysłem przemawia przede wszystkim format danych: klient przysyła JSONa, Node.js automatycznie parsuje go do obiektu JavaScript na którym można wykonać pewne operacje a później zapisać w bazie jako JSON znowu.

Klientem MongoDB w Node.js jest mongoose. Można go pobrać z menadżera pakietów poleceniem

npm install mongoose

Po dodaniu pakietu do serwera Node.js przy użyciu konstrukcji require, można rozpocząć pracę z MongoDB. Pakiet mongoose do CRUDowych operacji wykorzystuje obiekty typu Schema. Definiując taki obiekt podajemy jakiego typu pola znajdować się będą w naszych dokumentach. Dzięki temu, wstawiając dokument do bazy mamy pewność, że wstawione zostaną jedynie te pola, które zdefiniowaliśmy w schemacie. Mechanizm ten jest konfigurowalny poprzez opcję strict. Jeżeli ustawimy ją na false, to do bazy trafiać będą całe dokumenty. Jeden schemat mapowany będzie na jedną kolekcję w bazie przy zachowaniu zasad języka angielskiego. Na przykład schemat Car zmapowany zostanie do kolekcji cars. Poniżej prosta konfiguracja:
var mongoose = require('mongoose');
mongoose.connect('localhost','mongoosetest');

var schema = mongoose.Schema({ 
    make: 'string',
    enginePower : 'number'
 }, {strict: false});

var Car = mongoose.model('Car', schema);

Dodawanie dokumentów do bazy przy odbieraniu wiadomości typu POST:
app.post('/store/', function(req, resp) {
    var nm = req.body.name;
    var pw = req.body.enginePower;
    var car = new Car({ make: nm, enginePower: pw, day: "17-03" });
    car.save(function(err){
        if(err){
            resp.send({
                ok: 'sth went wrong'
            });
        }
        else{
            resp.send({
                ok: 'everything is fine'
            });
        }       
    });    
});

Analogicznie pobieranie danych wykonujemy także na obiekcie modelu;
app.get('/store/:key', function(req, resp) {
    Car.find({make: req.params.key}, function(err, docs){
        if(err)
            resp.send(501);
        else
            resp.send(docs);
    })
});

Funkcja find może przekazywać bardziej skomplikowane zapytania MongoDB, te same, które dostępne są w shellu bazy (program mongo.exe).

Z kolei aby usunąć obiekt, używamy funkcji remove wołanej również na modelu. Jako pierwszy parametr podaje się warunek.
app.del('/store/:key', function(req, resp) {
    Car.remove({make: req.params.key}, function(err, docs){
        if(err)
            resp.send(500);
        else
            resp.send(200);
    });
});

sobota, 28 lipca 2012

[Wzorce projektowe] Repository

Analogia z życia:

Chcąc wypożyczyć książki udajemy się do biblioteki. Osoby pracujące tam pomagają nam znaleźć interesujące nas pozycje, podają z magazynu egzemplarze, które nas interesują oraz wstawiają te, które chcemy oddać. W przypadku bibliotek samoobsługowych musielibyśmy wiedzieć o tym, w jaki sposób wyszukiwać i gdzie fizycznie szukać konkretnych egzemplarzy.



Zastosowanie:

Wszędzie tam, gdzie mamy do czynienia z dostępem do danych : połączenia SQL, pobieranie danych z plików, czy webserwisów. Wzorzec repozytorium zapewnia enkapsulację kodu odpowiadającego za połączenie ze źródłem danych w taki sposób. Jest to zatem warstwa pośrednia pomiędzy buissness logic, a źródłem danych, co ułatwia np. testowanie. Wzorzec często występuję w parze z wzorcem Unit of Work odpowiadającym za zatwierdzanie lub wycofywanie zmian.

Zasada działania:

Wprowadza się obiekt repozytorium udostępniający pewne API. W skład API wchodzą takie metody, jak dodawanie encji, usuwanie czy przeszukiwanie kolekcji encji. Bazowe API może być generycznym interfejsem, z którego dziedziczą konkretne repozytoria.

Przykład implementacyjny:

public interface IEntity
    {
        int Id { get; set; }
    }

    public class Customer : IEntity 
    {
        public string Name { get; set; }
        public string Mail { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public int Id { get; set; }
    }
public interface IRepository<T>
        where T : IEntity
    {
        void Add(T instance);
        void Remove(T instance);
        IEnumerable<T> Find(Predicate<T> predicate);
    }

    public class CustomerRepository : IRepository<Customer>
    {
        private List<Customer> _entities;

        private int _count;

        public CustomerRepository()
        {
            try
            {
               LoadDataFromXml();
            }
            catch (Exception)
            {
               Console.WriteLine("Unable to load data");
            }
        }

        public void LoadDataFromXml()
        {
            _entities = new List<Customer>();
            XDocument doc = XDocument.Load("Records.xml");
            var list = doc.Elements("records").Elements("record");
            foreach (var element in list)
            {
                IEnumerable<XElement> properties = element.Elements();
                var customer = new Customer();
                customer.Id = _count++;
                customer.Name = properties.ElementAt(0).Value;
                customer.Mail = properties.ElementAt(1).Value;
                customer.Address = properties.ElementAt(2).Value;
                customer.City = properties.ElementAt(3).Value;
                _entities.Add(customer);
                }
        }

        public void Add(Customer instance)
        {
            instance.Id = _count++;
            _entities.Add(instance);
        }

        public void Remove(Customer instance)
        {
            _entities.Remove(instance);
        }

        public IEnumerable<Customer> Find(Predicate<Customer> predicate)
        {
            return _entities.Where(customer => predicate(customer));
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            IRepository<Customer> repository = new CustomerRepository();

            var results = repository.Find(c => c.City.StartsWith("C"));
            foreach (Customer customer in results)
            {
                Console.WriteLine(customer.City);
            }

            repository.Add(new Customer()
                               {
                                   Name = "Jonnie Walker",
                                   Address = "Elm Street 12/9",
                                   Mail = "jwalker@mit.edu",
                                   City = "NY"
                               });

            Console.ReadKey();
        }
    }