Gün gelecek elasticsearch ile string alanda sıralama ve full-text arama yapmak istediğiniz zamanlar olacak. Full-text arama yapmak isterseniz, belirtilen alanın analyzed olması gerekir ama bu durumda ise sıralamanın sonucu yanlış olur. Doğru sıralama yapmak için, belirtilen alanın not_analyzed olması gerekir. Aşağıdaki örnek her iki indexin tek bir alana nasıl uygulanacağını gösterir. Bu örnek FOSElasticaBundle kullanıyor. Daha fazla bilgi için String Sorting and Multifields sayfasını okuyun.


Örnek veriler


Veritabanında aslında daha fazla bilgi var.


mysql> SELECT * FROM post LIMIT 10;
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| id | title | description | author | year | price | is_published | created_at |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| 1 | tit | ion | ed | 2010 | 2.50 | 1 | 2016-03-11 14:08:29 |
| 2 | alo | de | a edie | 2010 | 4.00 | 0 | 2016-03-11 14:08:29 |
| 3 | ula | tion | ed jon | 2010 | 1.00 | 1 | 2016-03-11 14:08:29 |
| 4 | des | ion | eddy | 2005 | 2.50 | 0 | 2016-03-11 14:08:29 |
| 5 | alo | de | ed | 2015 | 1.00 | 0 | 2016-03-11 14:08:29 |
| 6 | tit 1 | des | eddy | 2000 | 4.00 | 1 | 2016-03-11 14:08:29 |
| 7 | des | john | ed jon | 2015 | 4.00 | 0 | 2016-03-11 14:08:29 |
| 8 | des | des | edie | 2005 | 5.55 | 1 | 2016-03-11 14:08:29 |
| 9 | 2 tit | de 1 | ed jon | 2015 | 5.55 | 1 | 2016-03-11 14:08:29 |
| 10 | tit | des | jo | 2005 | 5.55 | 1 | 2016-03-11 14:08:29 |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
10 rows in set (0.00 sec)

Analyzed


Sonuçlar birbirlerine uymuyor. Belirtilen title alanında full-text arama yapabiliriz ama sıralama yapamayız.


Config


fos_elastica:
....
mappings:
title:
type: string
....

DB: Sorgu ve Sonuç


mysql> SELECT * FROM post ORDER BY title ASC, id ASC LIMIT 2 OFFSET 0;
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| id | title | description | author | year | price | is_published | created_at |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| 9 | 2 tit | de 1 | ed jon | 2015 | 5.55 | 1 | 2016-03-11 14:08:29 |
| 23 | 2 tit | io des | ed jon | 2010 | 3.99 | 0 | 2016-03-11 14:08:29 |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
2 rows in set (0.02 sec)

ES: Sorgu ve Sonuç


# Query
{
"query": {
"bool": {
"must": [
{
"match_all": []
}
]
}
},
"sort": [
{
"title": {
"order": "asc"
}
}
],
"from": 0,
"size": "2"
}

# Result
1) "id": 59 - "title": "tit 1"
2) "id": 78 - "title": "tit 1"

Not Analyzed


Sonuçlar birbirlerine uyuyor. Belirtilen title alanında sıralama yapabiliriz ama full-text arama yetimizi kaybettik. Sadece kesin değer arayabiliriz. Kısacası halen sorunumuz var.


Config


fos_elastica:
....
mappings:
title:
type: string
index: not_analyzed
....

DB: Sorgu ve Sonuç


mysql> SELECT * FROM post ORDER BY title ASC, id ASC LIMIT 2 OFFSET 0;
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| id | title | description | author | year | price | is_published | created_at |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| 9 | 2 tit | de 1 | ed jon | 2015 | 5.55 | 1 | 2016-03-11 14:08:29 |
| 23 | 2 tit | io des | ed jon | 2010 | 3.99 | 0 | 2016-03-11 14:08:29 |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
2 rows in set (0.02 sec)

ES: Sorgu ve Sonuç


# Query
{
"query": {
"bool": {
"must": [
{
"match_all": []
}
]
}
},
"sort": [
{
"title": {
"order": "asc"
}
}
],
"from": 0,
"size": "2"
}

# Result
1) "id": 9 - "title": "2 tit"
2) "id": 23 - "title": "2 tit"

Analyzed ve Not Analyzed


Sonuçlar birbirlerine uyuyor. Belirtilen title alanında hem sıralama hem de full-text arama yapabiliriz


Config


fos_elastica:
....
mappings:
title:
type: string
analyzer: english
fields:
raw:
type: string
index: not_analyzed
....

DB: Sorgu ve Sonuç


mysql> SELECT * FROM post ORDER BY title ASC, id ASC LIMIT 2 OFFSET 0;
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| id | title | description | author | year | price | is_published | created_at |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
| 9 | 2 tit | de 1 | ed jon | 2015 | 5.55 | 1 | 2016-03-11 14:08:29 |
| 23 | 2 tit | io des | ed jon | 2010 | 3.99 | 0 | 2016-03-11 14:08:29 |
+----+-------+-------------+--------+------+-------+--------------+---------------------+
2 rows in set (0.02 sec)

ES: Sorgu ve Sonuç


Siralama bölümünde title.raw, ara bölümünde ise title anahtarlarını kullanacaksınız.


# Query
{
"query": {
"bool": {
"must": [
{
"match_all": []
}
]
}
},
"sort": [
{
"title.raw": {
"order": "asc"
}
}
],
"from": 0,
"size": "2"
}

# Result
1) "id": 9 - "title": "2 tit"
2) "id": 23 - "title": "2 tit"