Развлекательный проект по написанию небольшой, простой поисковой системы, подходящей для Small Data™.
Запустите модульные тесты:
mix test --exclude external
Запустите все тесты, в том числе с использованием внешних сервисов. Например, тесты RedisIndex
:
mix test
убедитесь, что у вас есть правильная строка подключения для Redis в config/config.exs . Вы можете использовать docker-compose
, чтобы быстро запустить экземпляр Redis.
Каждый индекс в Cedrik представлен процессом с Index
@behaviour
. Чтобы индексировать что-то в индекс, просто вызовите Index.index_doc(something, :index_name, type)
, где something
будет картой или структурой Elixir (я бы рекомендовал создать структуру с полем id, которое реализует протокол Storable
- посмотрите lib/document.ex
и lib/agent_store.ex
для справки), type
должен быть одной из существующих реализаций индекса AgentIndex
или RedisIndex
. Последний аргумент Index.index_doc
является необязательным и по умолчанию имеет значение AgentIndex
.
Чтобы получить список существующих индексов, используйте Index.list/0
или Index.list/1
— они вернут список кортежей в формате {pid, name, module}
Это простой тип индекса в памяти, подходящий для данных, которые помещаются в память и которые не нужно сохранять.
Это индекс, поддерживаемый Redis. Чтобы это работало, у вас должен быть запущен и запущен экземпляр Redis. Основное преимущество использования RedisIndex по сравнению с AgentIndex заключается в том, что вы хотите иметь возможность сохранять данные.
На данный момент токен — это просто любая строка, разделенная пробелами.
Используйте Search.search(query_struct, [:index1, :index2])
, примеры см. test/e2e_test.exs
и test/query_test.exs
.
Чтобы получить структуру query_struct
, которую понимает Седрик, существует простой (и неполный) анализатор строк: Query.Parse.parse/1
. Он будет токенизировать строки, а затем соответственно создавать структуры запросов Term и Wildcard. Условия и подстановочные знаки будут заключены в логическое значение внутри обязательного поля.
Этот запрос вернет все идентификаторы документов в указанных индексах.
TermQuery просто возвращает идентификаторы документов (и расположение терминов в этом документе), которые содержат данный термин. Вы можете точно указать, в каких полях искать, или во всех (это значение по умолчанию).
С помощью BooleanQuery вы можете создавать более сложные запросы. must
, optional
и must_not
Этот запрос может помочь расширить область поиска. Например, групповой запрос со значением "foo*"
соответствует как foo, так и foobar. Обратите внимание, что на данный момент поддерживаются только одиночные подстановочные знаки, ведущие ( *foo
) или конечные ( foo*
).
На данный момент результаты Search.search/2
дадут вам список кортежей следующего вида: {doc_id, #MapSet<[%Location{field: :field, position: x}]>}
отсортированный по материалу с наибольшим количеством совпадений. первый.