Un proyecto divertido para escribir un motor de búsqueda pequeño e ingenuo adecuado para Small Data™.
Ejecute pruebas unitarias:
mix test --exclude external
Ejecute todas las pruebas, incluidas las que dependen de servicios externos. Como las pruebas RedisIndex
:
mix test
asegúrese de tener la cadena de conexión correcta para redis en config/config.exs . Puede utilizar docker-compose
para poner en funcionamiento rápidamente una instancia de Redis.
Cada índice en Cedrik está representado por un proceso con el Index
@behaviour
. Para indexar algo en un índice, simplemente llame a Index.index_doc(something, :index_name, type)
donde something
sería un mapa o estructura de Elixir (recomendaría crear una estructura, con un campo de identificación que implemente el protocolo Storable
; eche un vistazo a lib/document.ex
y lib/agent_store.ex
como referencia), type
debe ser una de las implementaciones de índice existentes AgentIndex
o RedisIndex
. El último argumento de Index.index_doc
es opcional y su valor predeterminado es AgentIndex
.
Para obtener una lista de índices existentes, utilice Index.list/0
o Index.list/1
; estos devolverán una lista de tuplas en el formato {pid, name, module}
Este es el tipo de índice ingenuo en memoria, adecuado para cosas que caben en la memoria y que no necesitan persistir.
Este es un índice respaldado por redis. Debe tener una instancia de Redis en funcionamiento para que esto funcione. El principal beneficio de utilizar RedisIndex en comparación con AgentIndex es cuando desea poder conservar los datos.
Por ahora, un token es simplemente cualquier cadena separada por espacios.
Utilice Search.search(query_struct, [:index1, :index2])
, consulte test/e2e_test.exs
y test/query_test.exs
para ver ejemplos.
Para obtener una query_struct
que Cedrik entienda, existe un analizador de cadenas simple (e incompleto): Query.Parse.parse/1
. Tokenizará cadenas y luego construirá estructuras de consulta de términos y comodines en consecuencia. Los términos y comodines se envolverán en un valor booleano, dentro del campo obligatorio.
Esta consulta devolverá todos los identificadores de documentos en los índices especificados.
Una TermQuery simplemente devuelve los identificadores del documento (y las ubicaciones del término dentro de ese documento) que contiene el término dado. Puede especificar exactamente en qué campos buscar, o todos ellos (que es el valor predeterminado).
Con BooleanQuery puedes construir consultas más avanzadas. must
, optional
y must_not
Esta consulta puede ayudar a ampliar sus visitas. Una consulta comodín con el valor "foo*"
coincide con foo y foobar, por ejemplo. Tenga en cuenta que por ahora solo se admiten comodines individuales, ya sean iniciales ( *foo
) o finales ( foo*
).
Por el momento, los resultados de Search.search/2
le darán una lista de tuplas que se ven así: {doc_id, #MapSet<[%Location{field: :field, position: x}]>}
ordenados por el material con más visitas primero.