View Source Searching with ArangoSearch
ArangoDB uses ArangoSearch to index collections to improve the searchability of them. With this you can do things like have multiple collections in one "view". A view is a concept that is essentially take one or more collections and indexes it using whatever "analyzer(s)" you choose to apply.
To query a View you just use it as if you were using any other collection schema. It will return the results the same as if you were querying that schema.
To create a View it is very similar to how you create a collection schema. The following will
create a view that has primary sorts on :created_at and :name, it will store the :email and the
:first_name & :last_name fields. Most importantly it will create a link to the MyApp.Users
schema and set the analyzer for the :name
field to :text_en
. Some options can be set also.
defmodule MyApp.UserSearch do
use ArangoXEcto.View
alias ArangoXEcto.View.Link
view "user_search" do
primary_sort :created_at, :desc
primary_sort :name
store_value [:email], :lz4
store_value [:first_name, :last_name], :none
link MyApp.Users, %Link{
includeAllFields: true,
fields: %{
name: %Link{
analyzers: [:text_en]
}
}
}
options [
primarySortCompression: :lz4
]
end
end
Querying is done exactly the same as a normal schema except the result will not be a struct.
iex> Repo.all(MyApp.UsersView)
[%{first_name: "John", last_name: "Smith"}, _]
You can find out more info in the ArangoXEcto.View
module.
To query using the search function you can use the ArangoXEcto.Query.search/3
and
ArangoXEcto.Query.or_search/3
functions. For example, if we wanted to search using the text
analyzer we could do the following.
import ArangoXEcto.Query
from(UsersView)
|> search([uv], fragment("ANALYZER(? == ?, \\"text_en\\")", uv.first_name, "John"))
|> Repo.all()