Недавно я начал использовать ElasticSearch, я планирую придерживаться его для сервиса, который я создаю.
В основном у меня есть следующие типы:
- поиски
- предложения
- цены предложений
Каждый поиск имеет набор информации плюс SID (идентификатор поиска), каждое предложение имеет OID (идентификатор предложения) плюс SID поиска и набор цен.
Я получаю данные асинхронно, чтобы не использовать _update, вместо того, чтобы иметь массив цен в предложении и обновлять его, каждая цена хранится в отдельном документе и содержит идентификатор поиска, идентификатор предложения и саму цену.
Я бы:
- фильтровать по SID
- агрегировать по OID
- сортировать агрегаты по цене
Как я мог это сделать? Любой намек? Я читаю документацию о том, как агрегировать, но понятия не имею :(
ИЗМЕНИТЬ:
Вот пример набора данных
ПОИСКИ (uuid — это sid)
{
'sid_1': { 'q': 'bread', 'sid': 'sid_1' },
'sid_2': { 'q': 'milk', 'sid': 'sid_2' },
'sid_3': { 'q': 'donuts', 'sid': 'sid_3' }
}
ПРЕДЛОЖЕНИЯ (uuid — это sid#oid)
{
'sid_1#kamut-bread': { 'name': 'kamut bread', 'sid': 'sid_1', 'oid': 'kamut-bread' },
'sid_1#chocolate-bread': { 'name': 'chocolate bread', 'sid': 'sid_1', 'oid': 'chocolate-bread' },
'sid_1#plastic-bread': { 'name': 'plastic bread', 'sid': 'sid_1', 'oid': 'plastic-bread' },
'sid_2#soya-milk': { 'name': 'soya milk', 'sid': 'sid_2', 'oid': 'soya-milk' },
'sid_2#vaccine-milk': { 'name': 'vaccine milk', 'sid': 'sid_2', 'oid': 'vaccine-milk' },
'sid_2#milk': { 'name': 'milk', 'sid': 'sid_2', 'oid': 'milk' },
'sid_3#cream-donuts': { 'name': 'cream donuts', 'sid': 'sid_3', 'oid': 'cream-donuts' },
'sid_3#chocolate-donuts': { 'name': 'chocolate donuts', 'sid': 'sid_3', 'oid': 'chocolate-donuts' },
'sid_3#square-donuts': { 'name': 'square donuts', 'sid': 'sid_3', 'oid': 'square-donuts' }
}
OFFERS_PRICES (uuid — партнер sid#oid#)
{
'sid_1#kamut-bread#amazon': { 'partner': 'amazon', 'sid': 'sid_1', 'oid': 'kamut-bread', 'price': 10.1, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#kamut-bread#store2': { 'partner': 'store2', 'sid': 'sid_1', 'oid': 'kamut-bread', 'price': 11.1, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#kamut-bread#store3': { 'partner': 'store3', 'sid': 'sid_1', 'oid': 'kamut-bread', 'price': 10.4, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#kamut-bread#store4': { 'partner': 'store4', 'sid': 'sid_1', 'oid': 'kamut-bread', 'price': 10.8, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#chocolate-bread#amazon': { 'partner': 'amazon', 'sid': 'sid_1', 'oid': 'chocolate-bread', 'price': 7.1, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#chocolate-bread#store2': { 'partner': 'store2', 'sid': 'sid_1', 'oid': 'chocolate-bread', 'price': 7.1, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#chocolate-bread#store3': { 'partner': 'store3', 'sid': 'sid_1', 'oid': 'chocolate-bread', 'price': 8.4, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#chocolate-bread#store4': { 'partner': 'store4', 'sid': 'sid_1', 'oid': 'chocolate-bread', 'price': 9.8, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#plastic-bread#amazon': { 'partner': 'amazon', 'sid': 'sid_1', 'oid': 'plastic-bread', 'price': 70.1, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#plastic-bread#store2': { 'partner': 'store2', 'sid': 'sid_1', 'oid': 'plastic-bread', 'price': 75.1, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#plastic-bread#store3': { 'partner': 'store3', 'sid': 'sid_1', 'oid': 'plastic-bread', 'price': 88.4, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } },
'sid_1#plastic-bread#store4': { 'partner': 'store4', 'sid': 'sid_1', 'oid': 'plastic-bread', 'price': 97.8, 'fees': { 'mastercard': 1, 'visa': 1, 'paypal': 2, 'wiretransfer': 0 } }
...
}
Из соображений производительности код не будет агрегировать данные, вместо этого он будет возвращать их отдельно (поиск, предложения и цены предложений), а внешний интерфейс будет их агрегировать, что позволит мне (почти) передавать данные напрямую из эластичны без необходимости их предварительной проработки.
После извлечения поиска и предложений я хотел бы:
- для извлечения цен на SID sid_1
- группировать цены по OID
- для сортировки агрегатов по цене (или по цене + конкретная плата, но я могу справиться с этим с groovy)