Skip to content

Commit dc4f09c

Browse files
authored
Merge pull request #24 from typesense/synonyms
Support for synonyms & operations
2 parents e9c5184 + 7bbe4ba commit dc4f09c

18 files changed

Lines changed: 369 additions & 24 deletions

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Tests are also a good place to know how the the library works internally: [spec]
3333

3434
| Typesense Server | typesense-ruby |
3535
|------------------|----------------|
36+
| \>= v0.18.0 | \>= v0.10.0 |
3637
| \>= v0.17.0 | \>= v0.9.0 |
3738
| \>= v0.16.0 | \>= v0.8.0 |
3839
| \>= v0.15.0 | \>= v0.7.0 |

examples/aliases.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
##
44
# These examples walk you through operations specifically related to aliases
5-
# # This is a Typesense Premium feature (see: https://typesense.org/premium)
6-
# Be sure to add `--license-key=<>` as a parameter, when starting a Typesense Premium server
75

86
require_relative './client_initialization'
97

examples/client_initialization.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@
1212
## Setup
1313
#
1414
### Option 1: Start a single-node cluster
15-
# $ docker run -i -p 8108:8108 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 8108 --enable-cors
15+
# $ docker run -i -p 8108:8108 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.18.0 --data-dir /data --api-key=xyz --listen-port 8108 --enable-cors
1616
#
1717
### Option 2: Start a 3-node cluster
1818
#
1919
# Create file in present working directory called typesense-server-peers (update IP Addresses appropriately to your local network):
2020
# $ echo '172.17.0.2:8107:8108,172.17.0.3:7107:7108,172.17.0.4:9107:9108' > `pwd`/typesense-server-peers
2121
#
2222
# Start node 1:
23-
# $ docker run -i -p 8108:8108 -p 8107:8107 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 8108 --peering-port 8107 --enable-cors --nodes=/typesense-server-peers
23+
# $ docker run -i -p 8108:8108 -p 8107:8107 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.18.0 --data-dir /data --api-key=xyz --listen-port 8108 --peering-port 8107 --enable-cors --nodes=/typesense-server-peers
2424
#
2525
# Start node 2:
26-
# $ docker run -i -p 7108:7108 -p 7107:7107 -v/tmp/.typesense-server-data-2b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 7108 --peering-port 7107 --enable-cors --nodes=/typesense-server-peers
26+
# $ docker run -i -p 7108:7108 -p 7107:7107 -v/tmp/.typesense-server-data-2b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.18.0 --data-dir /data --api-key=xyz --listen-port 7108 --peering-port 7107 --enable-cors --nodes=/typesense-server-peers
2727
#
2828
# Start node 3:
29-
# $ docker run -i -p 9108:9108 -p 9107:9107 -v/tmp/.typesense-server-data-3b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 9108 --peering-port 9107 --enable-cors --nodes=/typesense-server-peers
29+
# $ docker run -i -p 9108:9108 -p 9107:9107 -v/tmp/.typesense-server-data-3b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.18.0 --data-dir /data --api-key=xyz --listen-port 9108 --peering-port 9107 --enable-cors --nodes=/typesense-server-peers
3030
#
3131
# Note: Be sure to add `--license-key=<>` at the end when starting a Typesense Premium server
3232

@@ -64,5 +64,5 @@
6464
retry_interval_seconds: 0.01,
6565
connection_timeout_seconds: 10,
6666
logger: Logger.new($stdout),
67-
log_level: Logger::DEBUG
67+
log_level: Logger::INFO
6868
)

examples/overrides.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# frozen_string_literal: true
22

33
##
4-
# These examples walk you through operations specifically related to overrides
5-
# This is a Typesense Premium feature (see: https://typesense.org/premium)
6-
# Be sure to add `--license-key=<>` as a parameter, when starting a Typesense Premium server
4+
# These examples walk you through operations specifically related to result overrides / curation
75

86
require_relative './client_initialization'
97

8+
# Delete the collection if it already exists
9+
begin
10+
@typesense.collections['companies'].delete
11+
rescue Typesense::Error::ObjectNotFound
12+
end
13+
1014
##
1115
# Create a collection
1216
schema = {
@@ -63,16 +67,16 @@
6367
##
6468
# Create overrides
6569

66-
@typesense.collections['companies'].overrides.create(
67-
"id": 'promote-doofenshmirtz',
70+
@typesense.collections['companies'].overrides.upsert(
71+
'promote-doofenshmirtz',
6872
"rule": {
6973
"query": 'doofen',
7074
"match": 'exact'
7175
},
7276
"includes": [{ 'id' => '126', 'position' => 1 }]
7377
)
74-
@typesense.collections['companies'].overrides.create(
75-
"id": 'promote-acme',
78+
@typesense.collections['companies'].overrides.upsert(
79+
'promote-acme',
7680
"rule": {
7781
"query": 'stark',
7882
"match": 'exact'

examples/synonyms.rb

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# frozen_string_literal: true
2+
3+
##
4+
# These examples walk you through operations specifically related to synonyms
5+
6+
require_relative './client_initialization'
7+
8+
# Delete the collection if it already exists
9+
begin
10+
@typesense.collections['companies'].delete
11+
rescue Typesense::Error::ObjectNotFound
12+
end
13+
14+
##
15+
# Create a collection
16+
schema = {
17+
'name' => 'companies',
18+
'fields' => [
19+
{
20+
'name' => 'company_name',
21+
'type' => 'string'
22+
},
23+
{
24+
'name' => 'num_employees',
25+
'type' => 'int32'
26+
},
27+
{
28+
'name' => 'country',
29+
'type' => 'string',
30+
'facet' => true
31+
}
32+
],
33+
'default_sorting_field' => 'num_employees'
34+
}
35+
36+
@typesense.collections.create(schema)
37+
38+
# Let's create a couple documents for us to use in our search examples
39+
@typesense.collections['companies'].documents.create(
40+
'id' => '124',
41+
'company_name' => 'Stark Industries',
42+
'num_employees' => 5215,
43+
'country' => 'USA'
44+
)
45+
46+
@typesense.collections['companies'].documents.create(
47+
'id' => '127',
48+
'company_name' => 'Stark Corp',
49+
'num_employees' => 1031,
50+
'country' => 'USA'
51+
)
52+
53+
@typesense.collections['companies'].documents.create(
54+
'id' => '125',
55+
'company_name' => 'Acme Corp',
56+
'num_employees' => 1002,
57+
'country' => 'France'
58+
)
59+
60+
@typesense.collections['companies'].documents.create(
61+
'id' => '126',
62+
'company_name' => 'Doofenshmirtz Inc',
63+
'num_employees' => 2,
64+
'country' => 'Tri-State Area'
65+
)
66+
67+
##
68+
# Create synonyms
69+
70+
ap @typesense.collections['companies'].synonyms.upsert(
71+
'synonyms-doofenshmirtz',
72+
{
73+
'synonyms' => %w[Doofenshmirtz Heinz Evil]
74+
}
75+
)
76+
77+
##
78+
# Search for documents
79+
# Should return Doofenshmirtz Inc, since it's set as a synonym
80+
results = @typesense.collections['companies'].documents.search(
81+
'q' => 'Heinz',
82+
'query_by' => 'company_name'
83+
)
84+
ap results
85+
86+
##
87+
# List all synonyms
88+
ap @typesense.collections['companies'].synonyms.retrieve
89+
90+
##
91+
# Retrieve specific synonym
92+
ap @typesense.collections['companies'].synonyms['synonyms-doofenshmirtz'].retrieve
93+
94+
##
95+
# Update synonym to a one-way synonym
96+
ap @typesense.collections['companies'].synonyms.upsert(
97+
'synonyms-doofenshmirtz',
98+
{
99+
'root' => 'Evil',
100+
'synonyms' => %w[Doofenshmirtz Heinz]
101+
}
102+
)
103+
104+
##
105+
# Search for documents
106+
# Should return Doofenshmirtz Inc, since it's set as a synonym
107+
results = @typesense.collections['companies'].documents.search(
108+
'q' => 'Evil',
109+
'query_by' => 'company_name'
110+
)
111+
ap results
112+
113+
# Should not return any results, since this is a one-way synonym
114+
results = @typesense.collections['companies'].documents.search(
115+
'q' => 'Heinz',
116+
'query_by' => 'company_name'
117+
)
118+
ap results
119+
120+
##
121+
# Delete synonym
122+
ap @typesense.collections['companies'].synonyms['synonyms-doofenshmirtz'].delete
123+
124+
##
125+
# Cleanup
126+
# Drop the collection
127+
@typesense.collections['companies'].delete

lib/typesense.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ module Typesense
1313
require_relative 'typesense/document'
1414
require_relative 'typesense/overrides'
1515
require_relative 'typesense/override'
16+
require_relative 'typesense/synonyms'
17+
require_relative 'typesense/synonym'
1618
require_relative 'typesense/aliases'
1719
require_relative 'typesense/alias'
1820
require_relative 'typesense/keys'
1921
require_relative 'typesense/key'
2022
require_relative 'typesense/debug'
2123
require_relative 'typesense/health'
2224
require_relative 'typesense/metrics'
25+
require_relative 'typesense/operations'
2326
require_relative 'typesense/error'

lib/typesense/api_call.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def perform_request(method, endpoint, query_parameters: nil, body_parameters: ni
7878

7979
unless body_parameters.nil?
8080
body = body_parameters
81-
body = Oj.dump(body_parameters) if request_options[:headers]['Content-Type'] == 'application/json'
81+
body = Oj.dump(body_parameters, mode: :compat) if request_options[:headers]['Content-Type'] == 'application/json'
8282
request_options.merge!(body: body)
8383
end
8484

lib/typesense/client.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module Typesense
44
class Client
5-
attr_reader :configuration, :collections, :aliases, :keys, :debug, :health, :metrics
5+
attr_reader :configuration, :collections, :aliases, :keys, :debug, :health, :metrics, :operations
66

77
def initialize(options = {})
88
@configuration = Configuration.new(options)
@@ -13,6 +13,7 @@ def initialize(options = {})
1313
@debug = Debug.new(@api_call)
1414
@health = Health.new(@api_call)
1515
@metrics = Metrics.new(@api_call)
16+
@operations = Operations.new(@api_call)
1617
end
1718
end
1819
end

lib/typesense/collection.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
module Typesense
44
class Collection
5-
attr_reader :documents, :overrides
5+
attr_reader :documents, :overrides, :synonyms
66

77
def initialize(name, api_call)
88
@name = name
99
@api_call = api_call
1010
@documents = Documents.new(@name, @api_call)
1111
@overrides = Overrides.new(@name, @api_call)
12+
@synonyms = Synonyms.new(@name, @api_call)
1213
end
1314

1415
def retrieve

lib/typesense/operations.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
module Typesense
4+
class Operations
5+
RESOURCE_PATH = '/operations'
6+
7+
def initialize(api_call)
8+
@api_call = api_call
9+
end
10+
11+
def perform(operation_name, query_params = {})
12+
@api_call.post("#{RESOURCE_PATH}/#{operation_name}", {}, query_params)
13+
end
14+
end
15+
end

0 commit comments

Comments
 (0)