Hazırladığımız mapping bilgilerine göre elasticsearch index otomatik olarak yaratılır, bu nedenle çok fazla birşey yapmamız gerekmez. Ama eğer indexi kendiniz manuel olarak yaratmak veya manipüle etmek isterseniz, model_to_elastica_transformer servis seçeneğini kullanabilirsiniz. Bu gibi durumlarda mappings bilgilerini tanımlasanız bile, bunların hepsi index yaratılırken göz ardı edilir. Örneğimiz FOSElasticaBundle kullanıyor.

Aşağıdaki örneğimizde, "price" alanını manipüle edeceğiz. Değeri 4'den az olanları 1 yükseltip, diğerlerini de 1 azaltacağız. Bu sadece "published" alanı "true" olan kayılar için geçerlidir ve "false" olanlar hiçbir şekilde indexlenmeyecektir.


Veritabanı


mysql> SELECT * FROM post LIMIT 10;
+----+---------+-------------+---------------+------+-------+--------------+---------------------+
| id | title | description | author | year | price | is_published | created_at |
+----+---------+-------------+---------------+------+-------+--------------+---------------------+
| 1 | Desc | Cript B | Robert | 2000 | 5.55 | 1 | 2016-05-20 21:14:40 |
| 2 | Desc | Title | Andy Garcia | 2015 | 0.50 | 0 | 2016-05-20 21:15:00 |
| 3 | Eltit | Title 3 | Robert DeNiro | 2005 | 4.00 | 0 | 2016-05-20 21:15:00 |
| 4 | Eltit | Title 3 | Robert | 2015 | 3.99 | 1 | 2016-05-20 21:15:00 |
| 5 | Title 2 | Title 3 | Andy | 2000 | 4.00 | 1 | 2016-05-20 21:15:00 |
| 6 | Eltit B | Desc 1 | Andy | 2010 | 2.50 | 0 | 2016-05-20 21:15:00 |
| 7 | Title 2 | Desc 1 | Pacino | 2000 | 3.99 | 0 | 2016-05-20 21:15:00 |
| 8 | Title 1 | Desc 1 | DeNiro | 2010 | 5.55 | 1 | 2016-05-20 21:15:00 |
| 9 | Eltit A | Cript B | Andy Garcia | 2015 | 5.55 | 1 | 2016-05-20 21:15:00 |
| 10 | Eltit | Desc 2 | Pacino | 2000 | 3.99 | 0 | 2016-05-20 21:15:00 |
+----+---------+-------------+---------------+------+-------+--------------+---------------------+
10 rows in set (0.00 sec)

Elasticsearch sorgu


curl -XPOST "http://127.0.0.1:9200/_search?post_dev" -d'
{
"query": {
"bool": {
"must": [
{
"match_all": []
}
]
}
},
"sort": [
{
"id": {
"order": "id",
"ignore_unmapped": true
}
}
],
"from": "0",
"size": "10"
}'

Transformer olmayan örnek


Bu örnek veritabanındaki kayıları olduğu gibi indexleyecek ve sonuçları bize olduğu gibi verecektir.


Konfigürasyon


fos_elastica:
clients:
default: { host: 127.0.0.1, port: 9200 }
indexes:
post_index:
client: default
index_name: post_dev
types:
post:
mappings:
id:
type: integer
title:
type: string
description:
type: string
year:
type: integer
price:
type: double
is_published:
type: boolean
created_at:
type: date
persistence:
driver: orm
model: Application\SearchBundle\Entity\Post
finder: ~
provider: ~
listener: ~

Sorgu sonucu


{
"took": 2,
"timed_out": false,
"_shards": {
"total": 15,
"successful": 15,
"failed": 0
},
"hits": {
"total": 1003,
"max_score": null,
"hits": [
{
"_index": "post_dev",
"_type": "post",
"_id": "1",
"_score": null,
"_source": {
"id": 1,
"title": "Desc",
"description": "Cript B",
"year": "2000",
"price": "5.55",
"is_published": true,
"created_at": "2016-05-20T21:14:40+01:00"
},
"sort": [
1
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "2",
"_score": null,
"_source": {
"id": 2,
"title": "Desc",
"description": "Title",
"year": "2015",
"price": "0.50",
"is_published": false,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
2
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "3",
"_score": null,
"_source": {
"id": 3,
"title": "Eltit",
"description": "Title 3",
"year": "2005",
"price": "4.00",
"is_published": false,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
3
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "4",
"_score": null,
"_source": {
"id": 4,
"title": "Eltit",
"description": "Title 3",
"year": "2015",
"price": "3.99",
"is_published": true,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
4
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "5",
"_score": null,
"_source": {
"id": 5,
"title": "Title 2",
"description": "Title 3",
"year": "2000",
"price": "4.00",
"is_published": true,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
5
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "6",
"_score": null,
"_source": {
"id": 6,
"title": "Eltit B",
"description": "Desc 1",
"year": "2010",
"price": "2.50",
"is_published": false,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
6
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "7",
"_score": null,
"_source": {
"id": 7,
"title": "Title 2",
"description": "Desc 1",
"year": "2000",
"price": "3.99",
"is_published": false,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
7
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "8",
"_score": null,
"_source": {
"id": 8,
"title": "Title 1",
"description": "Desc 1",
"year": "2010",
"price": "5.55",
"is_published": true,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
8
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "9",
"_score": null,
"_source": {
"id": 9,
"title": "Eltit A",
"description": "Cript B",
"year": "2015",
"price": "5.55",
"is_published": true,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
9
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "10",
"_score": null,
"_source": {
"id": 10,
"title": "Eltit",
"description": "Desc 2",
"year": "2000",
"price": "3.99",
"is_published": false,
"created_at": "2016-05-20T21:15:00+01:00"
},
"sort": [
10
]
}
]
}
}

Transformer olan örnek


Bu örnekte sadece "published" alanı "true" olan kayıtlar indexlenecek, belirlenen alanlar seçilecek, bazı veriler değiştirilecek ve sorgu sonucunda bize sonuç olarak gösterilecekler. Eğer mappings bilgilerini tanımlasanız bile, bunların hepsi index yaratılırken göz ardı edilecektir.


Konfigürasyon


fos_elastica:
clients:
default: { host: 127.0.0.1, port: 9200 }
indexes:
post_index:
client: default
index_name: post_dev
types:
post:
mappings: ~
persistence:
driver: orm
model: Application\SearchBundle\Entity\Post
finder: ~
provider: ~
listener: ~
model_to_elastica_transformer:
service: application_search.service.post_to_elastica_transformer

Transformer class


Aşağıdaki $data['null'] = null; satırı, elasticsearch index içinede kayıt yaratmayı engellemek için kullanılır.


namespace Application\SearchBundle\Service;

use Application\SearchBundle\Entity\Post;
use DateTime;
use Elastica\Document;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;

class PostToElasticaTransformer implements ModelToElasticaTransformerInterface
{
const PRICE_CAP = 4;
const INCREASE_BY = 1;
const DECREASE_BY = 1;

/**
* @param Post $post
* @param array $fields
*
* @return Document
*/
public function transform($post, array $fields)
{
return new Document($post->getId(), $this->getData($post));
}

private function getData(Post $post)
{
$data = [];

if (!$post->getIsPublished()) {
$data['null'] = null;
} else {
$data['id'] = $post->getId();
$data['title'] = $post->getTitle();
$data['author'] = $post->getAuthor();
$data['year'] = (int)$post->getYear();
$data['price'] = (double)$post->getPrice();
$data['sale_price'] = $this->getSalePrice($post->getPrice());
$data['sale_price_created_at'] = (new DateTime())->format(DateTime::ISO8601);
}

return $data;
}

private function getSalePrice($price)
{
return $price < self::PRICE_CAP ? $price+self::INCREASE_BY : $price-self::DECREASE_BY;
}
}

Services.yml


services:
application_search.util.post_to_elastica_transformer:
class: Application\SearchBundle\Util\PostToElasticaTransformer

Sorgu sonucu


Aşağıda da gördüğümüz gibi, sadece "published" alanı "true" olan kayıtlar indexlenmiş ve birtakım yeni alanlar eklenmiş durumda.


{
"took": 4,
"timed_out": false,
"_shards": {
"total": 15,
"successful": 15,
"failed": 0
},
"hits": {
"total": 1003,
"max_score": null,
"hits": [
{
"_index": "post_dev",
"_type": "post",
"_id": "1",
"_score": null,
"_source": {
"id": 1,
"title": "Desc",
"author": "Robert",
"year": 2000,
"price": 5.55,
"sale_price": 4.55,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
1
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "4",
"_score": null,
"_source": {
"id": 4,
"title": "Eltit",
"author": "Robert",
"year": 2015,
"price": 3.99,
"sale_price": 4.99,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
4
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "5",
"_score": null,
"_source": {
"id": 5,
"title": "Title 2",
"author": "Andy",
"year": 2000,
"price": 4,
"sale_price": 3,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
5
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "8",
"_score": null,
"_source": {
"id": 8,
"title": "Title 1",
"author": "DeNiro",
"year": 2010,
"price": 5.55,
"sale_price": 4.55,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
8
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "9",
"_score": null,
"_source": {
"id": 9,
"title": "Eltit A",
"author": "Andy Garcia",
"year": 2015,
"price": 5.55,
"sale_price": 4.55,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
9
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "13",
"_score": null,
"_source": {
"id": 13,
"title": "Eltit",
"author": "Pacino",
"year": 2000,
"price": 0.5,
"sale_price": 1.5,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
13
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "14",
"_score": null,
"_source": {
"id": 14,
"title": "Title 2",
"author": "Robert DeNiro",
"year": 2000,
"price": 0.5,
"sale_price": 1.5,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
14
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "15",
"_score": null,
"_source": {
"id": 15,
"title": "Title 3",
"author": "Al",
"year": 2010,
"price": 2.5,
"sale_price": 3.5,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
15
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "17",
"_score": null,
"_source": {
"id": 17,
"title": "Title 2",
"author": "Al",
"year": 2005,
"price": 5.55,
"sale_price": 4.55,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
17
]
},
{
"_index": "post_dev",
"_type": "post",
"_id": "18",
"_score": null,
"_source": {
"id": 18,
"title": "Eltit",
"author": "Al",
"year": 2000,
"price": 4,
"sale_price": 3,
"sale_price_created_at": "2016-05-21T21:17:58+0100"
},
"sort": [
18
]
}
]
}
}