- Notifications
You must be signed in to change notification settings - Fork2
Clojure HTTP client for Typesense
License
runeanielsen/typesense-clj
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Clojure client forTypesense 27.1
All of the examples uses thetypesense.client
namespace. The examples shows the simplest way to get started using the client, but all parameters described on Typesense API documentation should work, if that is not the case, please make a pull-request or open an issue.
The values shown in the example might not be 100% up to date with the current Typesense version, please go to the Typesense documentation to be sure of the return values.
Two values are currently required for settings.
Uri
the base-uri for Typesense, an example is "https://localhost:8108".Key
the api-key required for the headerX-TYPESENSE-API-KEY
.
Example of settings.
(defsettings {:uri"http://localhost:8108":key"my-super-secret-api-key"})
This section describes how to use the collection, further information can be foundhere.
The differenttypes
for the schema can be foundhere.
The examples displays the creation of collection namedcompanies
.
(create-collection! settings {:name"companies":fields [{:name"company_name":type"string"} {:name"num_employees":type"int32"} {:name"country":type"string":facettrue}]:default_sorting_field"num_employees"});; Example success response =>{:default_sorting_field"num_employees":enable_nested_fieldsfalse:fields [{:facetfalse:indextrue:name"company_name":optionalfalse:stemfalse:type"string":infixfalse:locale"":sortfalse} {:facetfalse:indextrue:name"num_employees":optionalfalse:stemfalse:type"int32":infixfalse:locale"":sorttrue} {:facettrue:indextrue:name"country":optionalfalse:stemfalse:type"string":infixfalse:locale"":sortfalse}]:name"companies_collection_test":num_documents0:symbols_to_index []:token_separators []}
The differenttypes
for the schema can be foundhere.
The examples shows updating the collection named namedcompanies
with a new fieldyear_founded
.
(update-collection! settings"companies" {:fields [{:name"year_founded":type"int32":optionaltrue}]});; Example success response =>{:fields [{:facetfalse,:indextrue,:infixfalse,:locale"",:name"year_founded",:nestedfalse,:nested_array0,:num_dim0,:optionaltrue,:sorttrue,:stemfalse:type"int32",:vec_dist"cosine", +:embed nil, +:reference""}]}
Permanently drops a collection on thecollection-name
. This action cannot be undone.For large collections, this might have an impact on read latencies.
(delete-collection! settings"companies");; Example success response =>{:created_at1647261230:enable_nested_fieldsfalse:default_sorting_field"num_employees":fields [{:facetfalse:indextrue:name"company_name":optionalfalse:stemfalse:type"string"} {:facetfalse:indextrue:name"num_employees":optionalfalse:stemfalse:type"int32"} {:facettrue:indextrue:name"country":stemfalse:optionalfalse:type"string"}]:name"companies":num_documents0:symbols_to_index []:token_separators []}
Returns a summary of all your collections. The collections are returned sorted by creation date, with the most recent collections appearing first.
(list-collections settings);; Example success response =>[{:default_sorting_field"num_employees":enable_nested_fieldsfalse:fields [{:facetfalse:indextrue:name"company_name":optionalfalse:type"string":infixfalse:locale"":sortfalse} {:facetfalse:indextrue:name"num_employees":optionalfalse:type"int32":infixfalse:locale"":sorttrue} {:facettrue:indextrue:name"country":optionalfalse:type"string":infixfalse:locale"":sortfalse}]:name"companies_collection_test":num_documents0:symbols_to_index []:token_separators []}]
Retrieves the collection on thecollection-name
.
(retrieve-collection settings"companies");; Example success response =>{:default_sorting_field"num_employees":enable_nested_fieldsfalse:fields [{:facetfalse:indextrue:infixfalse:locale"":name"company_name":optionalfalse:sortfalse:type"string"} {:facetfalse:indextrue:infixfalse:locale"":name"num_employees":optionalfalse:sorttrue:type"int32"} {:facettrue:indextrue:infixfalse:locale"":name"country":optionalfalse:sortfalse:type"string"}]:name"companies_collection_test":num_documents0:symbols_to_index []:token_separators []}
This section describes how to use the documents, further information can be foundhere.
Creates the document in a given collection. The document should comply with theschema
of the collection.
(create-document! settings"companies" {:company_name"Stark Industries":num_employees5215:country"USA"});; Example success response =>{:company_name"Stark Industries":country"USA":id"0":num_employees5215}
Upsert the document in a given collection. The document will either be created or updated depending on if it already exists.
(upsert-document! settings"companies" {:company_name"Awesome Inc.":num_employees10:country"Norway"});; Example success response =>{:company_name"Awesome Inc.":num_employees10:country"Norway":id"1"}
Retrieves document in a collection onid
. Theid
can be parsed in asint
orstring
.
(retrieve-document settings"companies"1);; Example success response =>{:company_name"Awesome Inc.":num_employees10:country"Norway":id"1"}
Deletes document in a collection onid
. Theid
can be parsed in asint
orstring
.
(delete-document! settings"companies"1);; Example success response =>{:company_name"Stark Industries":country"USA":id"0":num_employees5215}
Update document in a collection on id. The update can be partial.
(update-document! settings"companies" {:company_name"Mega Awesome Inc."}1);; Example success response =>{:company_name"Mega Awesome Inc.":num_employees10:country"Norway":id"1"}
Create/upsert/update documents. All of them takes optional parameters, an example is setting the batch size using:batch_size 20
. Read morehere.
(create-documents! settings"companies" [{:company_name"Innovationsoft A/S":num_employees10:country"Finland"} {:company_name"GoSoftware":num_employees5000:country"Sweden"}]);; Example success response =>[{:successtrue} {:successtrue}]
(upsert-documents! settings"companies" [{:company_name"Innovationsoft A/S":num_employees10:country"Finland"} {:company_name"GoSoftware":num_employees5000:country"Sweden"}]);; Example success response =>[{:successtrue} {:successtrue}]
(update-documents! settings"companies" [{:id"1":company_name"Innovationsoft A/S":num_employees10:country"Finland"} {:id"2":company_name"GoSoftware":num_employees5000:country"Sweden"}]);; Example success response =>[{:successtrue} {:successtrue}]
Delete multiple documents on filter.
(delete-documents! settings"companies" {:filter_by"num_employees:>=100"});; Example success response =>{:num_deleted2}
Export documents in collection.
(export-documents settings"companies" {:filter_by"num_employees:>=100"});; Example success response =>[{:id"1":company_name"Innovationsoft A/S":num_employees10:country"Finland"}]
Search for documents in a collection. You can find all the query argumentshere.
(search settings"companies" {:q"Innovation":query_by"company_name"});; Example success response => {:facet_counts []:found1:hits [{:document {:company_name"Innovationsoft A/S":country"Finland":id"1":num_employees10}:highlight {:company_name {:matched_tokens ["Innovation"]:snippet"<mark>Innovation</mark>soft A/S"}}:highlights [{:field"company_name":matched_tokens ["Innovation"]:snippet"<mark>Innovation</mark>soft A/S"}]:text_match578730089005449337:text_match_info {:best_field_score"1108074561536":best_field_weight15:fields_matched1:score"578730089005449337":tokens_matched1}}]:out_of1:page1:request_params {:collection_name"companies_documents_test":per_page10:q"Innovation"}:search_cutofffalse:search_time_ms0}
You can send multiple search requests in a single HTTP request, using the Multi-Search feature. 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 read more about multi-searchhere.
(multi-search settings {:searches [{:collection"products":q"shoe":filter_by"price:=[50..120]"} {:collection"brands":q"Nike"}]} {:query_by"name"});; Example success response =>{:results [{:facet_counts []:found1:hits [{:document {:id"1":name"shoe":price75}:highlight {:name {:matched_tokens ["shoe"]:snippet"<mark>shoe</mark>"}}:highlights [{:field"name":matched_tokens ["shoe"]:snippet"<mark>shoe</mark>"}]:text_match578730123365711993:text_match_info {:best_field_score"1108091339008":best_field_weight15:fields_matched1:score"578730123365711993":tokens_matched1}}]:out_of1:page1:request_params {:collection_name"products_multi_search_test":per_page10:q"shoe"}:search_cutofffalse:search_time_ms0} {:facet_counts []:found1:hits [{:document {:id"1":name"Nike"}:highlight {:name {:matched_tokens ["Nike"]:snippet"<mark>Nike</mark>"}}:highlights [{:field"name":matched_tokens ["Nike"]:snippet"<mark>Nike</mark>"}]:text_match578730123365711993:text_match_info {:best_field_score"1108091339008":best_field_weight15:fields_matched1:score"578730123365711993":tokens_matched1}}]:out_of1:page1:request_params {:collection_name"brands_multi_search_test":per_page10:q"Nike"}:search_cutofffalse:search_time_ms0}]}
;; Create collection for geosearch with document.(let [schema {:name"places":fields [{:name"title":type"string"} {:name"points":type"int32"} {:name"location":type"geopoint"}]:default_sorting_field"points"} document {:points1:title"Louvre Museuem":location [48.860934816091142.33698396872901]}] (create-collection! settings schema) (create-document! settings"places" document));; Search(search settings"places" {:q"*":query_by"title":filter_by"location:(48.90615915923891 2.3435897727061175 5.1 km)":sort_by"location(48.853 2.344):asc"});; Example success response =>{:facet_counts []:found1:hits [{:document {:id"0":location [48.860934816091142.33698396872901]:points1:title"Louvre Museuem"}:geo_distance_meters {:location1020}:highlight {}:highlights []}]:out_of1:page1:request_params {:collection_name"places":per_page10:q"*"}:search_cutofffalse}
Typesense allows you to create API Keys with fine-grain access control. You can restrict access on both a per-collection and per-action level,read more here
(create-api-key! settings {:description"Search only companies key.":actions ["document:search"]:collections ["companies"]});; Example response =>{:actions ["document:search"]:collections ["companies"]:description"Search only companies key.":expires_at64723363199:autodeletefalse:id0:value"sK0jo6CSn1EBoJJ8LKPjRZCtsJ1JCFkt"}
Retrieves api key onid
.
(retrieve-api-key settings0);; Example response =>{:actions ["document:search"]:collections ["companies"]:description"Search only companies key.":expires_at64723363199:autodeletefalse:id0:value_prefix"vLbB"}
List all api keys.
(list-api-keys settings);; Example response =>{:keys [{:actions ["document:search"]:collections ["companies"]:description"Search only companies key.":expires_at64723363199:autodeletefalse:id0:value_prefix"vLbB"}]}
Deletes api key onid
.
(delete-api-key! settings0);; Example success response =>{:id0}
Using overrides, you can include or exclude specific documents for a given query, read morehere.
Create or update override if already exist.
(upsert-override! settings"companies""customize-apple" {:rule {:query"apple":match"exact"}:includes [{:id"422":position1} {:id"54":position2}]:excludes [{:id"287"}]});; Examples success response =>{:excludes [{:id"287"}]:id"customize_apple":includes [{:id"422":position1} {:id"54":position2}]:rule {:match"exact":query"apple"}}
List all overrides.
(list-overrides settings"companies");; Example success response =>{:overrides [{:excludes [{:id"287"}]:filter_curated_hitsfalse:id"customize_apple":includes [{:id"422":position1} {:id"54":position2}]:remove_matched_tokensfalse:rule {:match"exact":query"apple"}:stop_processingtrue}]}
Retrieves override on name.
(retrieve-override settings"companies""customize-apple");; Example success response =>{:excludes [{:id"287"}]:filter_curated_hitsfalse:id"customize_apple":includes [{:id"422":position1} {:id"54":position2}]:remove_matched_tokensfalse:rule {:match"exact":query"apple"}:stop_processingtrue}
Deletes override on name.
(delete-override! settings"companies""customize-apple");; Example success response =>{:id"customize_apple"}
An alias is a virtual collection name that points to a real collection. Read morehere
Create or update alias.
(upsert-alias! settings"companies" {:collection_name"companies_june11"});; Example success response =>{:collection_name"companies_june11":name"companies"}
Retrieve alias on collection-name.
(retrieve-alias settings"companies");; Example success response =>{:collection_name"companies_alias_test":name"companies"}
List aliases.
(list-aliases settings);; Example success response =>{:aliases [{:collection_name"companies_alias_test":name"companies"}]}
Delete alias on collection name.
(delete-alias! settings"companies");; Example success response =>{:collection_name"companies_alias_test":name"companies"}
The synonyms feature allows you to define search terms that should be considered equivalent, read morehere.
Create or update synonym.
(upsert-synonym! settings"products""coat-synonyms" {:synonyms ["blazer""coat""jacket"]});; Example success response =>{:id"coat-synonyms":synonyms ["blazer""coat""jacket"]}
Retrieve synonym on synonym name in collection.
(retrieve-synonym settings"products""coat-synonyms");; Example success response =>{:id"coat-synonyms":root"":synonyms ["blazer""coat""jacket"]}
List synonyms in collection.
(list-synonyms settings"products");; Example success response =>{:synonyms [{:id"coat-synonyms":root"":synonyms ["blazer""coat""jacket"]}]}
Delete synonym on synonym-name in collection.
(delete-synonym! settings"products""coat-synonyms");; Example success response =>{:id"coat-synonyms"}
Get health information about a Typesense node.
(health settings);; Example success response =>{:oktrue}
Get current RAM, CPU, Disk & Network usage metrics.
(metrics settings);; Example success response =>{:system_cpu8_active_percentage"0.00",:system_cpu12_active_percentage"9.09",:typesense_memory_allocated_bytes"87053184",:system_cpu5_active_percentage"9.09",:system_network_sent_bytes"475775",:system_cpu3_active_percentage"0.00",:system_cpu9_active_percentage"0.00",:typesense_memory_resident_bytes"97734656",:system_cpu_active_percentage"3.77",:system_memory_used_bytes"5583503360",:system_cpu14_active_percentage"9.09",:system_cpu15_active_percentage"0.00",:system_cpu6_active_percentage"0.00",:system_cpu10_active_percentage"10.00",:system_network_received_bytes"585752",:system_cpu13_active_percentage"0.00",:system_cpu11_active_percentage"0.00",:system_disk_total_bytes"16782462976",:typesense_memory_metadata_bytes"28598544",:system_cpu4_active_percentage"10.00",:system_cpu16_active_percentage"0.00",:typesense_memory_fragmentation_ratio"0.11",:system_disk_used_bytes"24072192",:system_memory_total_bytes"33564925952",:typesense_memory_mapped_bytes"255479808",:system_cpu2_active_percentage"18.18",:system_cpu1_active_percentage"9.09",:typesense_memory_retained_bytes"80064512",:system_cpu7_active_percentage"0.00",:typesense_memory_active_bytes"97734656"}
Get stats about API endpoints.Returns average requests per second and latencies for all requests in the last 10 seconds.
(stats settings);; Example success response =>{:import_latency_ms0:write_requests_per_second0:import_requests_per_second0:write_latency_ms0:latency_ms {}:pending_write_batches0:search_requests_per_second0:delete_requests_per_second0:search_latency_ms0:requests_per_second {}:total_requests_per_second0.0:overloaded_requests_per_second0:delete_latency_ms0}
Typesense API exceptions in theTypesense-api-errors spec.
Type | Description |
---|---|
:typesense.client/bad-request | Bad Request - The request could not be understood due to malformed syntax. |
:typesense.client/unauthorized | Unauthorized - Your API key is wrong. |
:typesense.client/not-found | Not Found - The requested resource is not found. |
:typesense.client/conflict | Conflict - When a resource already exists. |
:typesense.client/unprocessable-entity | Unprocessable Entity - Request is well-formed, but cannot be processed. |
:typesense.client/service-unavailable | Service Unavailable - We’re temporarily offline. Please try again later. |
:typesense.client/unspecified-api-error | If Typesense throws an error that is not specified in the spec. |
The following command runs only unit tests.
bin/kaocha unit
To run the integration tests you can run a local docker instance with the following command. This will start a instance of Typesense onlocalhost:8108
. The Typesense instance will be cleaned before starting the integration tests.
docker run -p 8108:8108 -v/tmp/data:/data typesense/typesense:27.1 --data-dir /data --api-key=key
The following command runs only the integration tests.
bin/kaocha integration
The following command runs all tests.
bin/kaocha
About
Clojure HTTP client for Typesense