Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

20.02.2024

Операції з часом в OpenSearch

Поступово дізнаюся нові можливості OpenSearch (та ElasticSearch), які, хоч і базові, але чомусь на поверхні не лежать. Сьогодні — про те, що дати набагато гнучкіше, ніж я собі думав.

Взагалі OpenSearch зберігає дати як числа. Проте, як я розумію з коду, різниця в індексації є: як я писав, числа OpenSearch індексує деревом множин, щоб швидше шукати за діапазоном. Для дат ці множини будуються не аби як, а за одиницями часу: хвилинами, годинами й так далі: ось код. Звісно, це саме те, чого ми хочемо від пошуку за часом.

Але це таке, знати не потрібно. А що варто знати, так це те, що час можна вказати зі скругленням до потрібної одиниці. Наприклад, потрібно мені знайти записи за останній тиждень. Як вказати верхню межу? Відома проблема, що просто датою не можна — відбитки часу за останню дату будуть технічно більші за дату без часу. Тому можна вдаватись до хаків: написати 23:59:59 (і втратити відбитки за останню хвилину!), чи зробити строго менше наступної дати. Проте в OpenSearch можна просто зробити запит зі скругленням до дня:

{
  "range": {
    "timestamp": {
      "gte": "2024-02-12||/d",
      "lte": "2024-02-18||/d"
    }
  }
}

(Ба більше, в цьому прикладі можна було б скруглити до тижня та ще спростити собі роботу.)

Та й повертати значення дати можна відразу в такому форматі, як нам потрібно: для документів з пошуку є опція docvalue_fields (дивна назва), а для агрегацій за датою просто format. Трохи незвично таке робити в базі, бо я звик, що бібліотека-клієнт віддає обʼєкти дати, з якими вже робиш що хочеш — проте за відсутністю такої бібліотеки дуже зручно.