Комментарии 13
1. Смогу ли я одновременно сделать WHERE и сделать полнотекстовый поиск по отдельной колонке?
2. Где в конечном счете хранится текст статьи в индексе elastic или в postgresql?
3. Возможно ли запрос к elastic, который идет в SQL, сделать на языке запросов elastic (например OR AND вставки или кастомные операторы какого-либо плагина к elastic)?
Да, можно. Можно искать как по полям Postgres, так и используя индексированные эластиком поля. Тоесть, 2 варианта:
SELECT test_elastic.text FROM test_elastic WHERE zdb('test_elastic', ctid) ==> 'text:(набор термов) and comments > 10';
и
SELECT test_elastic.text FROM test_elastic WHERE zdb('test_elastic', ctid) ==> 'text:(набор термов)' AND test_elastic.comments > 10;
будут работать
Текст дублирется в elastic в созданный индекс. Для каждого поля есть возможность указывать свой маппинг (ссылка на документацию), свои фильтры. Дополнительно, расширение создает в Postgres таблицы, в которых хранятся фильтры, маппинги и токенайзеры (например). Также, можно делать кастомные поисковые поля, объединяющие под собой существующие с одинаковым типом, на которые, видимо, можно вешать отдельно свой анализатор, что бы искать, например, и по шинглам, и по обычному. Но эту фичу я еще не проверял
- Да, это расширение парсит OR, AND, скобки. Есть свой набор операторов, которые умеет парсить (ссылка). Как простым способом определить свой dsl я пока не понял.
If there's a 3rd-party plugin that adds new analyzers, then ZomboDB can automatically support that too — you would just need to CREATE DOMAIN in Postgres for that analyzer and use that domain as your field type.
1) Yes, you can combine standard Postgres WHERE clause predicates with ZomboDB text-search queries. For example:
SELECT * FROM test_elastic WHERE comments > 10 AND zdb('test_elastic', ctid) ==> 'text:(term1,term2,termN, «this is a phrase)';
Postgres will plan the query accordingly, based on the types of indexes you have on your columns. ZomboDB text queries (==>) can also work when Postgres plans a sequential scan, so it's quite powerful here.
My experience is that with a large amount of data, it's significantly faster to just do everything within the ZomboDB text query. If you have a good Elasticsearch cluster, it's VERY fast!
2) ZomboDB stores the tokens of each column in Elasticsearch, not the whole row. ZomboDB also operates within Postgres' „Access Method API“ interface such that it's not very different than a standard „btree“ index, as far as Postgres is concerned. As such, your source of truth is *always* Postgres and the ZomboDB index stores the minimal amount of data in Elasticsearch to enable text searching.
3) ZomboDB has its own query language that supports quite a bit of the Elasticsearch QueryDSL (not everything, but very close!). Full boolean expressions are supported. If you needed to expose the functionality of a random Elasticsearch plugin to ZomboDB that would likely require changes to ZomboDB. If you see this is a thing you'd need to do often, I'd love to hear more details on ZomboDB's github page.
Thanks for your interest and I hope my answers have been helpful!
It was very cool that you feedback potential users in so unknown in non-russian internet resource =)
1. Может по подробнее расписать, чего не хватает в языке запросов в самом Postgres?
2. Если не хватало скорости то вы использовали GIN или GIST индекс?
3. Если нужно работать с тегами то ИМХО лучше воспользоватся intarray. В моём usecase мне помогло ну и в 9.6 я исправил планировщик (точнее оценку селективности, оно теперь пытается гистограммы использовать).
Спасибо.
- Задачи были: Искать похожие тексты, поиск по словосочетаниям. Также, была идея найти продукт, который позволит не писать отдельные запросы напрямую к elastic, а использовать его подобным образом.
- Да, на ts_vector есть индекс. Не хватало возможностей ts_vector из коробки. Вероятно, я что-то не знаю о его возможностях. Опять-же, см пункт 1 моего ответа.
- см пункт 1, задачи стояли не только в поиске по тегам. По тегам я просто описал пример синтаксиса запроса. Согласен, концептуально пример не очень валиден.
2. Использовали GIN.
Этот вопрос скорее всего в новой версии будет решён, там появилась возможность указывать расстояние между словами. Вроде уже в 9.6 есть. Могу конечно ошибаться но вроде оно…
tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'))
'fat' <-> 'cat'
tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10)
'fat' <10> 'cat'
Поиск по Postgres с использованием ZomboDb и elasticsearch