Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented basic multisearch endpoint support #35

Merged
merged 10 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ ex_typesense-*.tar
# Temporary files, for example, from tests.
/tmp/

# Zed editor
/.zed/

# Typesense local dev data folder.
/typesense-data

Expand Down
6 changes: 4 additions & 2 deletions .iex.exs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Ecto.Query, warn: false
alias ExTypesense.Cluster
alias ExTypesense.Collection
alias ExTypesense.Connection
alias ExTypesense.Document
alias ExTypesense.HttpClient
alias ExTypesense.Search
alias ExTypesense.TestSchema.Credential
alias ExTypesense.TestSchema.Person
alias ExTypesense.TestSchema.Catalog
alias ExTypesense.TestSchema.MultiSearch
alias ExTypesense.TestSchema.Person
alias ExTypesense.TestSchema.Product
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.6.0 (2024.07.15)

### Changed

* Move application env variables from `test_helper.exs` to `config` directory, in usage for both `dev` and `test` environments.

### Added

* Function: [multi search](https://typesense.org/docs/26.0/api/federated-multi-search.html)

## 0.5.0 (2024.07.13)

### Changed
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@

Typesense client for Elixir with support for your Ecto schemas.

> **Note**: Breaking changes if you're upgrading from `0.3.x` to `0.5.x` version.
> **Note**: Breaking changes if you're upgrading from `0.3.x` to `0.5.x` version and above.

## Todo

- creating collection using auto schema detection
- implement multisearch
- implement geosearch
- implement curation
- implement synonyms
Expand All @@ -28,7 +27,7 @@ Add `:ex_typesense` to your list of dependencies in the Elixir project config fi
def deps do
[
# From default Hex package manager
{:ex_typesense, "~> 0.5"}
{:ex_typesense, "~> 0.6"}

# Or from GitHub repository, if you want to latest greatest from main branch
{:ex_typesense, git: "https://github.com/jaeyson/ex_typesense.git"}
Expand Down
46 changes: 40 additions & 6 deletions guides/cheatsheet.cheatmd
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ iex> ExTypesense.create_collection(schema)
```elixir
iex> ExTypesense.list_collections()
```
{: .wrap}

### Update a collection

Expand Down Expand Up @@ -142,8 +143,6 @@ iex> ExTypesense.create_document(post, :create)
}
```

{: .wrap}

### Update a document

```elixir
Expand All @@ -161,8 +160,6 @@ iex> ExTypesense.update_document(post, 0)
}
```

{: .wrap}


### Delete a document

Expand Down Expand Up @@ -200,13 +197,14 @@ iex> ExTypesense.index_multiple_documents(posts, :post_id, :upsert)
{:ok, [%{"success" => true}, %{"success" => true}]}
```

## Search
## How to use search

{: .col-2}

### Search using Ecto schema (struct)

```elixir
iex> params = %{q: "test", query_by: "title"}

iex> ExTypesense.search(Post, params)
{:ok,
%{
Expand All @@ -218,3 +216,39 @@ iex> ExTypesense.search(Post, params)
}
}
```

### Multi search

```elixir
iex> searches = [
...> %{collection: "companies", q: "Loca Cola"},
...> %{collection: Company, q: "Burgler King"},
...> %{collection: Catalog, q: "umbrella"}
...> ]
iex> ExTypesense.multi_search(searches)
{:ok,
[
{
%{"facet_counts" => [], "found" => 0, "hits" => [], ...},
%{"facet_counts" => [], "found" => 0, "hits" => [], ...},
%{"facet_counts" => [], "found" => 0, "hits" => [], ...},
}
]
}
```

### Search using collection name (string)

```elixir
iex> params = %{q: "test", query_by: "title"}
iex> ExTypesense.search("posts", params)
{:ok,
%{
"id" => "0",
"collection_name" => "posts",
"post_id" => 34,
"title" => "test",
"description" => "lorem ipsum"
}
}
```
2 changes: 2 additions & 0 deletions lib/ex_typesense.ex
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ defmodule ExTypesense do
# geo search

# multisearch
defdelegate multi_search(conn \\ Connection.new(), searches), to: ExTypesense.Search
defdelegate multi_search_ecto(conn \\ Connection.new(), searches), to: ExTypesense.Search

# curation

Expand Down
16 changes: 9 additions & 7 deletions lib/ex_typesense/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule ExTypesense.Connection do

alias ExTypesense.HttpClient

@derive {Inspect, except: [:api_key]}
defstruct [:host, :api_key, :port, :scheme]

@typedoc since: "0.4.0"
Expand All @@ -17,20 +18,21 @@ defmodule ExTypesense.Connection do
}

@doc """
Fetches credentials either from application env or map.

## Examples
Setting new connection or using the default config.

Using the default credential from local development Typesense instance:
> #### On using this function {: .info}
> Functions e.g. `ExTypesense.search` don't need to explicitly pass this
> unless you want to use another connection. See `README` for more details.
> Also, `api_key` is hidden when invoking this function.

## Examples
iex> conn = ExTypesense.Connection.new()
%ExTypesense.Connection{
host: "localhost",
api_key: "xyz",
port: 8108,
scheme: "http"
scheme: "http",
...
}

"""
@doc since: "0.4.0"
@spec new(connection :: t() | map()) :: ExTypesense.Connection.t()
Expand Down
8 changes: 1 addition & 7 deletions lib/ex_typesense/document.ex
Original file line number Diff line number Diff line change
Expand Up @@ -537,12 +537,6 @@ defmodule ExTypesense.Document do
|> hd()
|> to_string

delete_documents_by_query(conn, name, %{filter_by: "#{virtual_field}:>0"})
delete_documents_by_query(conn, name, %{filter_by: "#{virtual_field}:>=0"})
end

# @spec do_delete_all_documents(Connection.t(), String.t()) :: response()
# defp do_delete_all_documents(conn, collection_name) do
# path = Path.join([ @collections_path, collection_name, @documents_path ])
# HttpClient.request(conn, %{method: :delete, path: path})
# end
end
35 changes: 21 additions & 14 deletions lib/ex_typesense/result_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,28 @@ defmodule ExTypesense.ResultParser do
@moduledoc false

@doc since: "0.1.0"
@spec hits_to_query(Enum.t(), module()) :: Ecto.Query.t()
def hits_to_query(hits, module_name) do
if Enum.empty?(hits) do
module_name
|> where([i], i.id in [])
else
primary_field = module_name.__schema__(:source) <> "_id"
@spec hits_to_query(Enum.t(), module() | String.t()) :: Ecto.Query.t()
def hits_to_query(hits, schema_name) when hits == [] do
schema_name
|> where([i], i.id in [])
end

def hits_to_query(hits, schema_name) when is_atom(schema_name) do
primary_field = schema_name.__schema__(:source) <> "_id"
do_hits_to_query(hits, schema_name, primary_field)
end

def hits_to_query(hits, schema_name) when is_binary(schema_name) do
do_hits_to_query(hits, schema_name, schema_name <> "_id")
end

values =
Enum.map(hits, fn %{"document" => document} ->
document[primary_field]
end)
def do_hits_to_query(hits, schema_name, primary_field) do
values =
Enum.map(hits, fn %{"document" => document} ->
document[primary_field]
end)

module_name
|> where([i], i.id in ^values)
end
schema_name
|> where([i], i.id in ^values)
end
end
Loading