Günümüz web uygulamalarında arama, özellikle metin arama (full text search) en karmaşık konulardan birisi haline gelmiş durumda. Performans kaygınız varsa veya seçtiğiniz veritabanı motoru (InnoDB?) full text search desteklemiyorsa harici bir arama motoru kullanmanız gerekli.
Solr ise "Lucene tabanlı arama motorları ailesi"nin bir üyesi. Lucene; temelde metin analizi, indexleme ve arama gibi temel işlevleri sunan bir Apache projesi. Solr ise, Lucene temelini kullanan, onun üstüne filtreleme, faceting(Türkçesi var mı acaba?), önbellekleme, dağıtık mimari desteği gibi şeyleri kolay yapılandırma dosyaları ile yönetebilmenizi ve bu verileri XML, JSON, Binary gibi çeşitli formatlarda almanızı sağlayan bir üst proje.
Zip'i açtığınızda içinde bir örnek uygulama bulunmakta. Eğer Java Runtime Environment'ınız kurulu ise aşağıdaki komutlarla Solr'ı çalıştırabilirsiniz.
Solr, öntanımlı olarak 8983 portunda çalışır. Tarayıcınızdan http://localhost:8983/solr/ adresini ziyaret ettiğinizde aşağıdaki gibi bir yönetim paneli arayüzü göreceksiniz. Sol altta da mevcut "collection"ları görebilirsiniz. Örnek collection'a tıkladığınızda da aşağıdaki gibi bir ekran göreceksiniz.
Örnek birkaç döküman eklemek için komut satırında
http://localhost:8983/solr/#/collection1 adresindeki yönetim paneline tekrar döndüğünüzde artık döküman sayınızın artığını görebilirsiniz.
Test etmek için;
Bunun yanında, örnek uygulama içinde, velocity template'ları ile geliştirilmiş "basit bir e-ticaret arama sayfası" da bulunuyor: http://localhost:8983/solr/browse
Artık "yaparak gösterme" kısmını geride bıraktığımıza göre biraz derine inmenin vakti geldi.
Bunun yanında uniqueId'yi belirleyebileceğimiz, bazı wildcard'lı field adları ile dynamic field'lar belirleyebileceğimiz, birden çok alanı tek alanda birleştirip arama yapabileceğimiz(copy) tanımlamaları bu dosyada belirtiyoruz.
Ayrıca, buradaki veri tiplerinin de class tanımlamaları ve varsa aldığı parametreler bu dosyada tanımlanıyor. Örnek içindeki dosya da şuradaki gibi: https://gist.github.com/anonymous/fb851195ea33e0fae9a7
Kendi döküman tipinizi schema.xml dosyasında belirleyebilirsiniz.
Solarium, sizin için, daha "anlaşılabilir" bir programlama arayüzü ile Solr istekleri yapmanızı ve bu istekleri "parse etmenizi" sağlıyor. Bunun yanında buffer'lı şekilde döküman ekleme gibi de bir çok güzellik sunuyor.
Solr ise "Lucene tabanlı arama motorları ailesi"nin bir üyesi. Lucene; temelde metin analizi, indexleme ve arama gibi temel işlevleri sunan bir Apache projesi. Solr ise, Lucene temelini kullanan, onun üstüne filtreleme, faceting(Türkçesi var mı acaba?), önbellekleme, dağıtık mimari desteği gibi şeyleri kolay yapılandırma dosyaları ile yönetebilmenizi ve bu verileri XML, JSON, Binary gibi çeşitli formatlarda almanızı sağlayan bir üst proje.
Solr Kurulumu
http://lucene.apache.org/solr/downloads.html adresinden Apache Solr'ın son sürümü (yazı hazırlanırken 4.4 sürümü vardı) indirebilirsiniz. Solr kaynak kodlarını indirebileceğiniz gibi içinde hazır örnek uygulamaların da olduğu bir paketi (solr-4.4.0.zip) indirebilirsiniz.Çalıştırma
Askere gidenler bilir; önce yaparak öğretme diye bir şey vardır. Bir eğitimi detaylı anlatmadan önce bir kere gösterir, sonra detaylara geçersiniz. Burada da önce, mevcut örnek uygulamayı bir çalıştırıp, sonra Solr'ın bir kaç yapılandırma dosyasını anlatacağım.Zip'i açtığınızda içinde bir örnek uygulama bulunmakta. Eğer Java Runtime Environment'ınız kurulu ise aşağıdaki komutlarla Solr'ı çalıştırabilirsiniz.
$ cd solr-4.4.0/example/ $ java -jar start.jar
Solr, öntanımlı olarak 8983 portunda çalışır. Tarayıcınızdan http://localhost:8983/solr/ adresini ziyaret ettiğinizde aşağıdaki gibi bir yönetim paneli arayüzü göreceksiniz. Sol altta da mevcut "collection"ları görebilirsiniz. Örnek collection'a tıkladığınızda da aşağıdaki gibi bir ekran göreceksiniz.
Şu anda hiç "döküman"ımız yok. Solr her şeyi bir "döküman" olarak saklar. Dökümanları veritabanındaki "row"lar olarak düşünebilirsiniz. Örnek solr uygulaması, "exampledocs" isimli bir dizinde bir çok hazır döküman bulunduruyor. Daha sonra bu dökümanlara ve şemalara deyineceğim ama önce "yaparak göstermek" açısından örnek dökümanları ekleyip basit bir kaç arama yapalım.
Örnek birkaç döküman eklemek için komut satırında
$ cd exampledocs $ java -jar post.jar *.xmlkomutlarını verdiğinizde aşağıdaki gibi bir çıktı alacaksınız
SimplePostTool version 1.5 Posting files to base url http://localhost:8983/solr/update using content-type application/xml.. POSTing file gb18030-example.xml POSTing file hd.xml POSTing file ipod_other.xml POSTing file ipod_video.xml POSTing file manufacturers.xml POSTing file mem.xml POSTing file money.xml POSTing file monitor2.xml POSTing file monitor.xml POSTing file mp500.xml POSTing file sd500.xml POSTing file solr.xml POSTing file utf8-example.xml POSTing file vidcard.xml 14 files indexed. COMMITting Solr index changes to http://localhost:8983/solr/update.. Time spent: 0:00:00.268
http://localhost:8983/solr/#/collection1 adresindeki yönetim paneline tekrar döndüğünüzde artık döküman sayınızın artığını görebilirsiniz.
Test etmek için;
- http://localhost:8983/solr/collection1/query?q=* ile tüm dökümanları görebilir,
- http://localhost:8983/solr/collection1/query?q=+asus +price:[400 TO 1000] ile içerisinde 'asus' kelimesi geçen ve fiyatı 400 ile 1000 arasında olan ürünleri filtreleyebilir,
- http://localhost:8983/solr/collection1/query?q=features:power&sort=price+asc ile 'features' field'ında power geçenleri fiyata göre sıralayabilir
- http://localhost:8983/solr/collection1/query?q=asus&hl=true&hl.fl=name ile içerisnde asus geçen kayıtları bulup "vurgulama"(highlight) için <em> html tagi ile çevrelenmesini sağlayabilir
- http://localhost:8983/solr/collection1/spell?q=conan gibi bir "yazım hatası" için düzeltme önerileri (did you mean?) alabilir
- http://localhost:8983/solr/collection1/query/?q=*:*&facet=true&facet.field=cat&fl=id ile de tüm sonuçları 'cat' alanına göre facet'layarak (kısaca, o 'cat' alanında bulunan kayıt sayısını dönerek) sonuçları listelemesini, fl parametresi ile de sadece 'id' alanını dönmesini sağlayabilirsiniz.
Bunun yanında, örnek uygulama içinde, velocity template'ları ile geliştirilmiş "basit bir e-ticaret arama sayfası" da bulunuyor: http://localhost:8983/solr/browse
Artık "yaparak gösterme" kısmını geride bıraktığımıza göre biraz derine inmenin vakti geldi.
solrconfig.xml
İlgili collection'ın "conf" dizini altında bulunan bu dosyada solr genel yapılandırma ayarları, yukarıdaki örneklerde "query", "select", "spell" gibi farklı adreslerde gördüğünüz, bazı öntanımlı değerleri verip bazı ayarları yapabileceğiniz "requestHandler"lar, isteğe dönen cevap tipini ayarlayabileceğiniz queryResponseWriter'ları tanımlayabilirsiniz. Örnek içindeki dosya şuradaki gibi: https://gist.github.com/anonymous/038d4c991297a9352e5aschema.xml
Daha önce bahsettiğim gibi, solr'daki her kayıt bir "döküman". Schema.xml de bu "döküman"ı tanımlamamız gereken dosya. <fields> alanındaki her <field> relational database'lerden alışık olduğumuz "column"lara denk geliyor. Burada kabaca field'ımızın adı(name), solr aramalarında kullanılıp kullanılmayacağı(indexed), bulunan kayıtlarda cevaplar içinde dönüp dönmeyeceği(stored), birden çok değer alıp alamayacağı(multiValued) ve hangi tipte bir veri içereceği(type)ni belirttiğimiz alanları içerir.Bunun yanında uniqueId'yi belirleyebileceğimiz, bazı wildcard'lı field adları ile dynamic field'lar belirleyebileceğimiz, birden çok alanı tek alanda birleştirip arama yapabileceğimiz(copy) tanımlamaları bu dosyada belirtiyoruz.
Ayrıca, buradaki veri tiplerinin de class tanımlamaları ve varsa aldığı parametreler bu dosyada tanımlanıyor. Örnek içindeki dosya da şuradaki gibi: https://gist.github.com/anonymous/fb851195ea33e0fae9a7
Kendi döküman tipinizi schema.xml dosyasında belirleyebilirsiniz.
PHP ve Solr
Solr temelde HTTP istekleri ile çalıştığı için, basitçe cURL istekleri ile veriyi alıp, responseWriter olarak da json kullanırsanız basitçe verileri decode edip PHP içinde array ve obje olarak kullanabilirsiniz. Örnek olarak yukarıdaki ilk örneği aşağıdaki gibi Object olarak kullanabilirsiniz PHP tarafında.<?php $url = "http://localhost:8983/solr/collection1/query?q=*"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = json_decode(curl_exec($ch)); curl_close ($ch); var_dump($response);Ama istekler çeşitlenmeye başladığında istek yapmanız gereken adres çok karmaşık bir hal lamaya başlayacak. Curl ile uğraşıp, url generate etmek istemiyorsanız da Solarium gibi daha "high level" bir kütüphane kullanabilirsiniz.
Solarium, sizin için, daha "anlaşılabilir" bir programlama arayüzü ile Solr istekleri yapmanızı ve bu istekleri "parse etmenizi" sağlıyor. Bunun yanında buffer'lı şekilde döküman ekleme gibi de bir çok güzellik sunuyor.
Solarium kurulum
Solarium'u projenize dahil etmek için birçok yol olsa da, en güzeli composer ile eklemek. composer.json dosyanıza aşağıdaki "require" satırını ekledikten sonra composer install demeniz yeterli.{ "require": { "solarium/solarium": "3.1.2" } }
Veri ekleme
<?php require __DIR__. '/vendor/autoload.php'; $config = array( 'endpoint' => array( 'localhost' => array( 'host' => '127.0.0.1', 'port' => 8983, 'path' => '/solr/', ) ) ); $client = new Solarium\Client($config); $update = $client->createUpdate(); // dokumanı oluşturuyoruz $doc = $update->createDocument(); $doc->id = 1; $doc->name = "Sonsuzdongu"; $doc->cat = "Yazılım"; // sonra dokumani commit'liyoruz $update->addDocument($doc); $update->addCommit(); // ve update sorgusunu calistiriyoruz $result = $client->update($update); // artik dokumanimiz eklendi var_dump($result);
Veri Filtreleme
<?php require __DIR__. '/vendor/autoload.php'; $config = array( 'endpoint' => array( 'localhost' => array( 'host' => '127.0.0.1', 'port' => 8983, 'path' => '/solr/', ) ) ); $client = new Solarium\Client($config); $query = $client->createSelect(); // filtre olustur $query->createFilterQuery('name')->setQuery('name:sonsuzdongu'); $resultSet = $client->select($query); echo 'Toplam: '.$resultSet->getNumFound(); //sonuclari ekrana bas foreach($resultSet as $result) { var_dump($result->name); }Gördüğünüz gibi Solarium ile cURL ile yaptığımızdan daha "semantik" şekilde sorguları çalıştırıp sonuçları alabiliyoruz. Solr ve Solarium'dan şimdilik bu kadar.