Skip to content

Commit

Permalink
allow module name to be passed as collection name
Browse files Browse the repository at this point in the history
  • Loading branch information
jaeyson committed Jul 4, 2024
1 parent bdb1abd commit deb4b1f
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 32 deletions.
40 changes: 32 additions & 8 deletions guides/cheatsheet.cheatmd
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ iex> ExTypesense.create_collection(schema)
```elixir
iex> ExTypesense.list_collections()
```
{: .wrap}

### Update a collection

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

{: .wrap}

### Update a document

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

{: .wrap}


### Delete a document

Expand All @@ -177,8 +174,6 @@ iex> ExTypesense.delete_document(Post, 0)
}
```

{: .wrap}

### Indexes multiple documents

```elixir
Expand All @@ -187,13 +182,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 @@ -205,3 +201,31 @@ iex> ExTypesense.search(Post, params)
}
}
```

### Multi search

```elixir
iex> ExTypesense.multisearch(Catalog)
```

### 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"
}
}
```

### Federated search

```elixir
iex> ExTypesense.multisearch(Catalog)
```
86 changes: 63 additions & 23 deletions lib/ex_typesense/search.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ defmodule ExTypesense.Search do
@documents_path "documents"
@search_path "search"
@multi_search_path "/multi_search"
@type response :: Ecto.Query.t() | {:ok, map()} | {:error, map()}
@type response :: {:ok, map()} | {:error, map()}

@doc """
Search from a document.
Search from a document or Ecto Schema.
Search params can be found [here](https://typesense.org/docs/latest/api/search.html#search-parameters).
## Examples
iex> params = %{q: "umbrella", query_by: "title,description"}
iex> ExTypesense.search(Something, params)
iex> ExTypesense.search(Catalog, params)
{:ok,
%{
"facet_counts" => [],
Expand All @@ -30,7 +31,26 @@ defmodule ExTypesense.Search do
"out_of" => 0,
"page" => 1,
"request_params" => %{
"collection_name" => "something",
"collection_name" => "catalogs",
"per_page" => 10,
"q" => "umbrella"
},
"search_cutoff" => false,
"search_time_ms" => 5
}
}
iex> params = %{q: "umbrella", query_by: "title,description"}
iex> ExTypesense.search("catalogs", params)
{:ok,
%{
"facet_counts" => [],
"found" => 0,
"hits" => [],
"out_of" => 0,
"page" => 1,
"request_params" => %{
"collection_name" => "catalogs",
"per_page" => 10,
"q" => "umbrella"
},
Expand All @@ -41,7 +61,7 @@ defmodule ExTypesense.Search do
"""
@doc since: "0.1.0"
@spec search(Connection.t(), module() | String.t(), map()) :: response()
@spec search(Connection.t(), module() | String.t(), map()) :: Ecto.Query.t() | response()
def search(conn \\ Connection.new(), module_or_collection_name, params)

def search(conn, module_name, params) when is_atom(module_name) and is_map(params) do
Expand Down Expand Up @@ -75,13 +95,25 @@ defmodule ExTypesense.Search do
end

@doc """
Perform multiple searches at once.
Perform [multiple/federated](https://typesense.org/docs/latest/api/federated-multi-search.html)
searches at once.
Search params can be found [here](https://typesense.org/docs/latest/api/search.html#search-parameters).
> This is especially useful to avoid round-trip network latencies
> incurred otherwise if each of these requests are sent in separate
> HTTP requests.
> You can also use this feature to do a federated search across
> multiple collections in a single HTTP request. For eg: in an
> ecommerce products dataset, you can show results from both a
> "products" collection, and a "brands" collection to the user, by
> searching them in parallel with a multi_search request.
## Examples
iex> searches = [
...> %{collection: "companies", params: %{q: "umbrella"}},
...> %{collection: "companies", params: %{q: "rain"}},
...> %{collection: "companies", params: %{q: "sun"}}
...> %{collection: "companies", q: "Loca Cola"},
...> %{collection: Company, q: "Burgler King"},
...> %{collection: Catalog, q: "umbrella"}
...> ]
iex> ExTypesense.multi_search(searches)
{:ok,
Expand All @@ -95,7 +127,7 @@ defmodule ExTypesense.Search do
"request_params" => %{
"collection_name" => "companies",
"per_page" => 10,
"q" => "umbrella"
"q" => "Loca Cola"
},
"search_cutoff" => false,
"search_time_ms" => 5
Expand All @@ -109,7 +141,7 @@ defmodule ExTypesense.Search do
"request_params" => %{
"collection_name" => "companies",
"per_page" => 10,
"q" => "rain"
"q" => "Burgler King"
},
"search_cutoff" => false,
"search_time_ms" => 5
Expand All @@ -123,7 +155,7 @@ defmodule ExTypesense.Search do
"request_params" => %{
"collection_name" => "companies",
"per_page" => 10,
"q" => "sun"
"q" => "umbrella"
},
"search_cutoff" => false,
"search_time_ms" => 5
Expand All @@ -135,16 +167,24 @@ defmodule ExTypesense.Search do
def multi_search(conn \\ Connection.new(), searches) do
path = @multi_search_path

response =
HttpClient.request(
conn,
%{
method: :post,
path: path,
body: Jason.encode!(%{searches: searches})
}
)

response
searches =
Enum.map(searches, fn %{collection: name} = search ->
collection_name =
case is_binary(name) do
true -> name
false -> name.__schema__(:source)
end

Map.put(search, :collection, collection_name)
end)

HttpClient.request(
conn,
%{
method: :post,
path: path,
body: Jason.encode!(%{searches: searches})
}
)
end
end
6 changes: 5 additions & 1 deletion test/search_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ defmodule SearchTest do
assert {:ok, %{"found" => 0, "hits" => []}} = ExTypesense.search(schema.name, params)
end

# test "success: multi_search Ecto", %{schema: schema} do
# test "success: multi_search Ecto", %{catalog: catalog} do
# assert nil == true
# end

# test "success: multi_search contains string or module name as collection name", %{schema: schema} do
# assert nil == true
# end

Expand Down

0 comments on commit deb4b1f

Please sign in to comment.