milvus 0.9.3 β†’ 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0b1a3fa88ea1e79f7a139441dc0665e4631ecf160a9d1507a556ef2e3aedb74
4
- data.tar.gz: 1a215e718b86ffb2eab1b103d60d02b60ef493f90c88bcb28e05f0f1f6d07fa4
3
+ metadata.gz: 4333b7321ee1e40f8f390692f6e25ce991837cd6b51bf6dfb4eef48fcfc826e9
4
+ data.tar.gz: c84d6a7f8be503c0009676a0d659d43bc5e443442f49a9bc6d96824da5904579
5
5
  SHA512:
6
- metadata.gz: d41d1ddf7d468d69b857bf07fc70926dca0193656768359250e038340211c4798e44390b337edcbee632a8b9e5a104fd082a2b506e0fa90a46c48627a55d4ef6
7
- data.tar.gz: fbbc287d804be3babdd0ff9f3a08bd0ebacfcfa3e7d2338397d431784e4b2b5143889d5fc067a82ab33d06a93525bbd9a2f772a949238dbbcbe8bddff75cb19d
6
+ metadata.gz: 2fffcbee8f0596ab3b65d12992a6323518a1a9ee1cb5c6c5d8437bbabcfa123acc8c777a189932fdc1be1b9b283c14f449e29dab27dc6b23d5c0dc7f333c3a42
7
+ data.tar.gz: a6d589ffa1c4e2b1e95eb74d1a089727a51adfdd265e852db52bf0558baeceb3f8e78b3fd53133efffce212c683bc38a5dc54bb5b0cc6662e32c74180ca7b4db
data/.env.example ADDED
@@ -0,0 +1,2 @@
1
+ MILVUS_URL=http://localhost:19530
2
+ MILVUS_API_KEY=
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2023-04-20
3
+ ## [0.10.0] - 2024-07-04 πŸ‡ΊπŸ‡Έ
4
+ - BREAKING: Switched the gem to use newer V2 API with different endpoints and corresponding endpoints.
4
5
 
6
+ ## [0.9.3] - 2023-07-01
7
+
8
+ ## [0.9.2] - 2023-08-10
9
+
10
+ ## [0.9.1] - 2023-05-10
11
+
12
+ ## [0.9.0] - 2023-04-21
5
13
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- milvus (0.9.3)
4
+ milvus (0.10.0)
5
5
  faraday (>= 2.0.1, < 3)
6
6
 
7
7
  GEM
@@ -68,11 +68,7 @@ GEM
68
68
  unicode-display_width (2.4.2)
69
69
 
70
70
  PLATFORMS
71
- arm64-darwin-23
72
- x86_64-darwin-19
73
- x86_64-darwin-21
74
- x86_64-darwin-22
75
- x86_64-linux
71
+ ruby
76
72
 
77
73
  DEPENDENCIES
78
74
  milvus!
@@ -82,4 +78,4 @@ DEPENDENCIES
82
78
  standard (~> 1.27.0)
83
79
 
84
80
  BUNDLED WITH
85
- 2.4.0
81
+ 2.5.14
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Milvus
2
2
 
3
3
  <p>
4
- <img alt='Milvus logo' src='https://res.cloudinary.com/crunchbase-production/image/upload/c_lpad,f_auto,q_auto:eco,dpr_1/cqpyxcuzl6gwqjjwzamt' height='50' />
5
- +&nbsp;&nbsp;
4
+ <img alt='Milvus logo' src='https://milvus.io/images/milvus_logo.svg' height='50' />
5
+ &nbsp;&nbsp;
6
6
  <img alt='Ruby logo' src='https://user-images.githubusercontent.com/541665/230231593-43861278-4550-421d-a543-fd3553aac4f6.png' height='40' />
7
7
  </p>
8
8
 
@@ -10,11 +10,17 @@ Ruby wrapper for the Milvus vector search database API.
10
10
 
11
11
  Part of the [Langchain.rb](https://github.com/andreibondarev/langchainrb) stack.
12
12
 
13
+ Available for paid consulting engagements! [Email me](mailto:andrei@sourcelabs.io).
14
+
13
15
  ![Tests status](https://github.com/andreibondarev/milvus/actions/workflows/ci.yml/badge.svg)
14
16
  [![Gem Version](https://badge.fury.io/rb/milvus.svg)](https://badge.fury.io/rb/milvus)
15
17
  [![Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/gems/milvus)
16
18
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/andreibondarev/milvus/blob/main/LICENSE.txt)
17
19
  [![](https://dcbadge.vercel.app/api/server/WDARp7J2n8?compact=true&style=flat)](https://discord.gg/WDARp7J2n8)
20
+ [![X](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Follow%20%40rushing_andrei)](https://twitter.com/rushing_andrei)
21
+
22
+ ## API Docs
23
+ https://docs.zilliz.com/reference/restful/data-plane-v2
18
24
 
19
25
  ## Installation
20
26
 
@@ -34,14 +40,28 @@ If bundler is not being used to manage dependencies, install the gem by executin
34
40
  require 'milvus'
35
41
 
36
42
  client = Milvus::Client.new(
37
- url: 'http://localhost:9091'
43
+ url: 'http://localhost:19530'
38
44
  )
39
45
  ```
40
46
 
41
47
  ### Using the Collections endpoints
48
+ ```ruby
49
+ # Check if the collection exists.
50
+ client.collections.has(collection_name: "book")
51
+ ```
52
+
53
+ ```ruby
54
+ # Rename a collection.
55
+ client.collections.rename(collection_name: "book", new_collection_name: "note")
56
+ ```
57
+
58
+ ```ruby
59
+ # Get collection stats
60
+ client.collections.get_stats(collection_name: "book")
61
+ ```
42
62
 
43
63
  ```ruby
44
- # Data types: "boolean", "int8", "int16", "int32", "int64", "float", "double", "string", "varchar", "binary_vector", "float_vector"
64
+ # Data types: https://github.com/patterns-ai-core/milvus/blob/main/lib/milvus/constants.rb
45
65
 
46
66
  # Creating a new collection schema
47
67
  client.collections.create(
@@ -50,46 +70,47 @@ client.collections.create(
50
70
  auto_id: false,
51
71
  fields: [
52
72
  {
53
- "name": "book_id",
73
+ "fieldName": "book_id",
54
74
  "description": "book id",
55
- "is_primary_key": true,
75
+ "isPrimary": true,
56
76
  "autoID": false,
57
- "data_type": Milvus::DATA_TYPES["int64"]
77
+ "dataType": "Int64"
58
78
  },
59
79
  {
60
- "name": "word_count",
80
+ "fieldName": "word_count",
61
81
  "description": "count of words",
62
- "is_primary_key": false,
63
- "data_type": Milvus::DATA_TYPES["int64"]
82
+ "isPrimary": false,
83
+ "dataType": "Int64"
64
84
  },
65
85
  {
66
- "name": "book_intro",
86
+ "fieldName": "book_intro",
67
87
  "description": "embedded vector of book introduction",
68
- "data_type": Milvus::DATA_TYPES["binary_vector"],
69
- "is_primary_key": false,
70
- "type_params": [
71
- {
72
- "key": "dim",
73
- "value": "2"
74
- }
75
- ]
88
+ "dataType": "FloatVector",
89
+ "isPrimary": false,
90
+ "elementTypeParams": {
91
+ "dim": "2"
92
+ }
76
93
  }
77
94
  ]
78
95
  )
79
96
  ```
80
97
  ```ruby
81
- # Get the collection info
82
- client.collections.get(collection_name: "book")
98
+ # Descrbie the collection
99
+ client.collections.describe(collection_name: "book")
83
100
  ```
84
101
  ```ruby
85
- # Delete the collection
86
- client.collections.delete(collection_name: "book")
102
+ # Drop the collection
103
+ client.collections.drop(collection_name: "book")
87
104
  ```
88
105
  ```ruby
89
106
  # Load the collection to memory before a search or a query
90
107
  client.collections.load(collection_name: "book")
91
108
  ```
92
109
  ```ruby
110
+ # List all collections in the specified database.
111
+ client.collections.list
112
+ ```
113
+ ```ruby
93
114
  # Release a collection from memory after a search or a query to reduce memory usage
94
115
  client.collections.release(collection_name: "book")
95
116
  ```
@@ -140,91 +161,126 @@ client.entities.compact_status(
140
161
  # => {"status"=>{}, "state"=>2}
141
162
  ```
142
163
 
143
- ### Indices
164
+ ### Indexes
144
165
  ```ruby
145
- client.indices.create(
146
- collection_name: "book",
147
- field_name: "book_intro",
148
- extra_params: [
149
- { key: "metric_type", "value": "L2" },
150
- { key: "index_type", "value": "IVF_FLAT" },
151
- { key: "params", "value": "{\"nlist\":1024}" }
152
- ]
166
+ # Create an index
167
+ index_params = {
168
+ fieldName: "example_field",
169
+ indexType: "IVF_FLAT",
170
+ metricType: "L2",
171
+ params: { nlist: 100 }
172
+ }
173
+
174
+ client.indexes.create(
175
+ collection_name: "example_collection",
176
+ index_params: index_params
153
177
  )
154
178
  ```
155
179
  ```ruby
156
- collection.indices.create(
157
- field_name: "book_name",
158
- index_name: "scalar_index",
180
+ # Describe an index
181
+ client.indexes.describe(
182
+ collection_name: "example_collection",
183
+ index_name: "example_index"
159
184
  )
160
185
  ```
161
186
  ```ruby
162
- client.indices.delete(
163
- collection_name: "book",
164
- field_name: "book_intro"
187
+ # List indexes
188
+ client.indexes.list(
189
+ collection_name: "example_collection"
190
+ )
191
+ ```
192
+ ```ruby
193
+ # Drop an index
194
+ client.indexes.drop(
195
+ collection_name: "example_collection",
196
+ index_name: "example_index"
165
197
  )
166
198
  ```
167
199
 
168
- ### Search & Querying
200
+ ### Search, Querying & Hybrid Search
169
201
  ```ruby
170
- client.search(
171
- collection_name: "book",
172
- output_fields: ["book_id"], # optional
173
- anns_field: "book_intro",
174
- top_k: "2",
175
- params: "{\"nprobe\": 10}",
176
- metric_type: "L2",
177
- round_decimal: "-1",
178
- vectors: [ [0.1,0.2] ],
179
- dsl_type: 1
202
+ client.entities.search(
203
+ collection_name: "recipes",
204
+ anns_field: "vectors",
205
+ data: [embedding],
206
+ filter: "id in [450847466900987454]"
180
207
  )
181
208
  ```
182
209
  ```ruby
183
- client.query(
184
- collection_name: "book",
185
- output_fields: ["book_id", "book_intro"],
186
- expr: "book_id in [2,4,6,8]"
210
+ client.entities.query(
211
+ collection_name: "recipes",
212
+ filter: "id in [450847466900987455, 450847466900987454]"
213
+ )
214
+ ```
215
+ ```ruby
216
+ client.entities.hybrid_search(
217
+ collection_name: "recipes",
218
+ search: [{
219
+ filter: "id in [450847466900987455]",
220
+ data: [embedding],
221
+ annsField: "vectors",
222
+ limit: 10,
223
+ outputFields: ["content", "id"]
224
+ }],
225
+ rerank: {
226
+ "strategy": "rrf",
227
+ "params": {
228
+ "k": 10
229
+ }
230
+ },
231
+ limit: 10,
232
+ output_fields: ["content", "id"]
187
233
  )
188
234
  ```
189
235
 
190
236
  ### Partitions
191
237
  ```ruby
192
- client.partitions.create(
193
- "collection_name": "book",
194
- "partition_name": "novel"
238
+ # List partitions
239
+ client.partitions.list(
240
+ collection_name: "example_collection"
195
241
  )
196
242
  ```
197
243
  ```ruby
198
- client.partitions.get(
199
- "collection_name": "book",
200
- "partition_name": "novel"
244
+ # Create a partition
245
+ client.partitions.create(
246
+ collection_name: "example_collection",
247
+ partition_name: "example_partition"
201
248
  )
202
249
  ```
203
250
  ```ruby
204
- client.partitions.delete(
205
- "collection_name": "book",
206
- "partition_name": "novel"
251
+ # Check if a partition exists
252
+ client.partitions.has(
253
+ collection_name: "example_collection",
254
+ partition_name: "example_partition"
207
255
  )
208
256
  ```
209
257
  ```ruby
258
+ # Load partition data into memory
210
259
  client.partitions.load(
211
- "collection_name": "book",
212
- "partition_names": ["novel"],
213
- "replica_number": 1
260
+ collection_name: "example_collection",
261
+ partition_names: ["example_partition"]
214
262
  )
215
263
  ```
216
264
  ```ruby
265
+ # Release partition data from memory
217
266
  client.partitions.release(
218
- "collection_name": "book",
219
- "partition_names": ["novel"],
220
- "replica_number": 1
267
+ collection_name: "example_collection",
268
+ partition_names: ["example_partition"]
221
269
  )
222
270
  ```
223
-
224
- ### Health
225
271
  ```ruby
226
- # Live determines whether the application is alive. It can be used for Kubernetes liveness probe.
227
- client.health
272
+ # Get statistics of a partition
273
+ client.partitions.get_stats(
274
+ collection_name: "example_collection",
275
+ partition_name: "example_partition"
276
+ )
277
+ ```
278
+ ```ruby
279
+ # Drop a partition
280
+ client.partitions.drop(
281
+ collection_name: "example_collection",
282
+ partition_name: "example_partition"
283
+ )
228
284
  ```
229
285
 
230
286
  ## Development
@@ -235,7 +291,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
235
291
 
236
292
  ## Contributing
237
293
 
238
- Bug reports and pull requests are welcome on GitHub at https://github.com/andreibondarev/milvus.
294
+ Bug reports and pull requests are welcome on GitHub at https://github.com/patterns-ai-core/milvus.
239
295
 
240
296
  ## License
241
297
 
data/lib/milvus/client.rb CHANGED
@@ -6,20 +6,13 @@ module Milvus
6
6
  class Client
7
7
  attr_reader :url, :api_key
8
8
 
9
- API_VERSION = "api/v1"
9
+ API_VERSION = "v2/vectordb"
10
10
 
11
- def initialize(
12
- url:,
13
- api_key: nil
14
- )
11
+ def initialize(url:, api_key: nil)
15
12
  @url = url
16
13
  @api_key = api_key
17
14
  end
18
15
 
19
- def health
20
- @health ||= Milvus::Health.new(client: self).get
21
- end
22
-
23
16
  def collections
24
17
  @schema ||= Milvus::Collections.new(client: self)
25
18
  end
@@ -32,16 +25,8 @@ module Milvus
32
25
  @entities ||= Milvus::Entities.new(client: self)
33
26
  end
34
27
 
35
- def indices
36
- @indices ||= Milvus::Indices.new(client: self)
37
- end
38
-
39
- def search(...)
40
- @search ||= Milvus::Search.new(client: self).post(...)
41
- end
42
-
43
- def query(...)
44
- @query ||= Milvus::Query.new(client: self).post(...)
28
+ def indexes
29
+ @indexes ||= Milvus::Indexes.new(client: self)
45
30
  end
46
31
 
47
32
  def connection
@@ -2,20 +2,67 @@
2
2
 
3
3
  module Milvus
4
4
  class Collections < Base
5
- PATH = "collection"
5
+ PATH = "collections"
6
+
7
+ # This operation checks whether a collection exists.
8
+ #
9
+ # @param collection_name [String] The name of the collection to check.
10
+ # @return [Hash] Server response
11
+ def has(collection_name:)
12
+ response = client.connection.post("#{PATH}/has") do |req|
13
+ req.body = {
14
+ collectionName: collection_name
15
+ }.to_json
16
+ end
17
+ response.body
18
+ end
19
+
20
+ # This operation renames an existing collection and optionally moves the collection to a new database.
21
+ #
22
+ # @param collection_name [String] The name of the collection to rename.
23
+ # @param new_collection_name [String] The new name of the collection.
24
+ # @return [Hash] Server response
25
+ def rename(collection_name:, new_collection_name:)
26
+ response = client.connection.post("#{PATH}/rename") do |req|
27
+ req.body = {
28
+ collectionName: collection_name,
29
+ newCollectionName: new_collection_name
30
+ }
31
+ end
32
+ response.body.empty? ? true : response.body
33
+ end
34
+
35
+ # This operation gets the number of entities in a collection.
36
+ #
37
+ # @param collection_name [String] The name of the collection to get the count of.
38
+ # @return [Hash] Server response
39
+ def get_stats(collection_name:)
40
+ response = client.connection.post("#{PATH}/get_stats") do |req|
41
+ req.body = {
42
+ collectionName: collection_name
43
+ }.to_json
44
+ end
45
+ response.body
46
+ end
6
47
 
7
48
  # Create a Collection
49
+ #
50
+ # @param collection_name [String] The name of the collection to create.
51
+ # @param auto_id [Boolean] Whether to automatically generate IDs for the collection.
52
+ # @param description [String] A description of the collection.
53
+ # @param fields [Array<Hash>] The fields of the collection.
54
+ # @return [Hash] Server response
8
55
  def create(
9
56
  collection_name:,
10
57
  auto_id:,
11
58
  description:,
12
59
  fields:
13
60
  )
14
- response = client.connection.post(PATH) do |req|
61
+ response = client.connection.post("#{PATH}/create") do |req|
15
62
  req.body = {
16
- collection_name: collection_name,
63
+ collectionName: collection_name,
17
64
  schema: {
18
- auto_id: auto_id,
65
+ autoId: auto_id,
19
66
  description: description,
20
67
  fields: fields,
21
68
  name: collection_name # This duplicated field is kept for historical reasons.
@@ -25,41 +72,76 @@ module Milvus
25
72
  response.body.empty? ? true : response.body
26
73
  end
27
74
 
28
- # Retrieve a Collection
29
- def get(collection_name:)
30
- response = client.connection.get(PATH) do |req|
75
+ # Describes the details of a collection.
76
+ #
77
+ # @param collection_name [String] The name of the collection to describe.
78
+ # @return [Hash] Server response
79
+ def describe(collection_name:)
80
+ response = client.connection.post("#{PATH}/describe") do |req|
31
81
  req.body = {
32
- collection_name: collection_name
82
+ collectionName: collection_name
33
83
  }.to_json
34
84
  end
35
85
  response.body
36
86
  end
37
87
 
38
- # Drop a Collection
39
- def delete(collection_name:)
40
- response = client.connection.delete(PATH) do |req|
88
+ # This operation lists all collections in the specified database.
89
+ #
90
+ # @return [Hash] Server response
91
+ def list
92
+ response = client.connection.post("#{PATH}/list") do |req|
93
+ req.body = {}
94
+ end
95
+ response.body
96
+ end
97
+
98
+ # This operation drops the current collection and all data within the collection.
99
+ #
100
+ # @param collection_name [String] The name of the collection to drop.
101
+ # @return [Hash] Server response
102
+ def drop(collection_name:)
103
+ response = client.connection.post("#{PATH}/drop") do |req|
41
104
  req.body = {
42
- collection_name: collection_name
105
+ collectionName: collection_name
43
106
  }.to_json
44
107
  end
45
108
  response.body.empty? ? true : response.body
46
109
  end
47
110
 
48
111
  # Load the collection to memory before a search or a query
112
+ #
113
+ # @param collection_name [String] The name of the collection to load.
114
+ # @return [Hash] Server response
49
115
  def load(collection_name:)
50
116
  response = client.connection.post("#{PATH}/load") do |req|
51
117
  req.body = {
52
- collection_name: collection_name
53
- }.to_json
118
+ collectionName: collection_name
119
+ }
54
120
  end
55
121
  response.body.empty? ? true : response.body
56
122
  end
57
123
 
124
+ # This operation returns the load status of a specific collection.
125
+ #
126
+ # @param collection_name [String] The name of the collection to get the load status of.
127
+ # @return [Hash] Server response
128
+ def get_load_state(collection_name:)
129
+ response = client.connection.post("#{PATH}/get_load_state") do |req|
130
+ req.body = {
131
+ collectionName: collection_name
132
+ }
133
+ end
134
+ response.body
135
+ end
136
+
58
137
  # Release a collection from memory after a search or a query to reduce memory usage
138
+ #
139
+ # @param collection_name [String] The name of the collection to release.
140
+ # @return [Hash] Server response
59
141
  def release(collection_name:)
60
- response = client.connection.delete("#{PATH}/load") do |req|
142
+ response = client.connection.post("#{PATH}/release") do |req|
61
143
  req.body = {
62
- collection_name: collection_name
144
+ collectionName: collection_name
63
145
  }.to_json
64
146
  end
65
147
  response.body.empty? ? true : response.body
@@ -4,59 +4,171 @@ module Milvus
4
4
  class Entities < Base
5
5
  PATH = "entities"
6
6
 
7
- # Insert the data to the collection.
7
+ # This operation inserts data into a specific collection.
8
+ #
9
+ # @param collection_name [String] The name of the collection to insert data into.
10
+ # @param data [Array<Hash>] The data to insert.
11
+ # @param partition_name [String] The name of the partition to insert the data into.
12
+ #
13
+ # @return [Hash] The response from the server.
8
14
  def insert(
9
15
  collection_name:,
10
- fields_data:,
11
- num_rows:,
16
+ data:,
12
17
  partition_name: nil
13
18
  )
14
- response = client.connection.post(PATH) do |req|
19
+ response = client.connection.post("#{PATH}/insert") do |req|
15
20
  req.body = {
16
- collection_name: collection_name,
17
- fields_data: fields_data,
18
- num_rows: num_rows
19
- }.to_json
21
+ collectionName: collection_name,
22
+ data: data
23
+ }
20
24
 
21
- req.body["partition_name"] = partition_name if partition_name
25
+ req.body[:partitionName] = partition_name if partition_name
22
26
  end
23
27
  response.body.empty? ? true : response.body
24
28
  end
25
29
 
26
- # Delete the entities with the boolean expression you created
30
+ # This operation deletes entities by their IDs or with a boolean expression.
31
+ #
32
+ # @param collection_name [String] The name of the collection to delete entities from.
33
+ # @param filter [String] The filter to use to delete entities.
34
+ # @return [Hash] The response from the server.
27
35
  def delete(
28
36
  collection_name:,
29
- expression:
37
+ filter:
30
38
  )
31
- response = client.connection.delete(PATH) do |req|
39
+ response = client.connection.post("#{PATH}/delete") do |req|
32
40
  req.body = {
33
- collection_name: collection_name,
34
- expr: expression
41
+ collectionName: collection_name,
42
+ filter: filter
35
43
  }.to_json
36
44
  end
37
45
  response.body.empty? ? true : response.body
38
46
  end
39
47
 
40
- # Compact data manually
41
- def compact!(
42
- collection_id:
48
+ # This operation conducts a filtering on the scalar field with a specified boolean expression.
49
+ #
50
+ # @param collection_name [String] The name of the collection to query.
51
+ # @param filter [String] The filter to use to query the collection.
52
+ # @param output_fields [Array<String>] The fields to return in the results.
53
+ # @param limit [Integer] The maximum number of results to return.
54
+ def query(
55
+ collection_name:,
56
+ filter:,
57
+ output_fields: [],
58
+ limit: nil
43
59
  )
44
- response = client.connection.post("compaction") do |req|
60
+ response = client.connection.post("#{PATH}/query") do |req|
45
61
  req.body = {
46
- collectionID: collection_id
47
- }.to_json
62
+ collectionName: collection_name,
63
+ filter: filter
64
+ }
65
+ req.body[:outputFields] = output_fields if output_fields
66
+ req.body[:limit] = limit if limit
48
67
  end
49
68
  response.body.empty? ? true : response.body
50
69
  end
51
70
 
52
- # Check compaction status
53
- def compact_status(
54
- compaction_id:
71
+ # This operation inserts new records into the database or updates existing ones.
72
+ #
73
+ # @param collection_name [String] The name of the collection to upsert data into.
74
+ # @param data [Array<Hash>] The data to upsert.
75
+ # @param partition_name [String] The name of the partition to upsert the data into.
76
+ # @return [Hash] The response from the server.
77
+ def upsert(
78
+ collection_name:,
79
+ data:,
80
+ partition_name: nil
55
81
  )
56
- response = client.connection.get("compaction/state") do |req|
82
+ response = client.connection.post("#{PATH}/upsert") do |req|
57
83
  req.body = {
58
- compactionID: compaction_id
59
- }.to_json
84
+ collectionName: collection_name,
85
+ data: data
86
+ }
87
+
88
+ req.body[:partitionName] = partition_name if partition_name
89
+ end
90
+ response.body.empty? ? true : response.body
91
+ end
92
+
93
+ # This operation gets specific entities by their IDs
94
+ #
95
+ # @param collection_name [String] The name of the collection to get entities from.
96
+ # @param id [Array<Integer>] The IDs of the entities to get.
97
+ # @param output_fields [Array<String>] The fields to return in the results.
98
+ # @return [Hash] The response from the server.
99
+ def get(
100
+ collection_name:,
101
+ id:,
102
+ output_fields: nil
103
+ )
104
+ response = client.connection.post("#{PATH}/get") do |req|
105
+ req.body = {
106
+ collectionName: collection_name,
107
+ id: id
108
+ }
109
+ req.body[:outputFields] = output_fields if output_fields
110
+ end
111
+ response.body.empty? ? true : response.body
112
+ end
113
+
114
+ # This operation conducts a vector similarity search with an optional scalar filtering expression.
115
+ #
116
+ # @param collection_name [String] The name of the collection to search.
117
+ # @param data [Array<Array<Float>>] The data to search for.
118
+ # @param anns_field [String] The field to search for.
119
+ # @param limit [Integer] The maximum number of results to return.
120
+ # @param output_fields [Array<String>] The fields to return in the results.
121
+ # @param offset [Integer] The offset to start from.
122
+ # @param filter [String] The filter to use to search the collection.
123
+ # @return [Hash] The search results.
124
+ def search(
125
+ collection_name:,
126
+ data:,
127
+ anns_field:,
128
+ limit: nil,
129
+ output_fields: [],
130
+ offset: nil,
131
+ filter: nil
132
+ )
133
+ response = client.connection.post("#{PATH}/search") do |req|
134
+ params = {
135
+ collectionName: collection_name,
136
+ data: data,
137
+ annsField: anns_field
138
+ }
139
+ params[:limit] = limit if limit
140
+ params[:outputFields] = output_fields if output_fields.any?
141
+ params[:offset] = offset if offset
142
+ params[:filter] = filter if filter
143
+ req.body = params
144
+ end
145
+ response.body.empty? ? true : response.body
146
+ end
147
+
148
+ # Executes a hybrid search.
149
+ #
150
+ # @param collection_name [String] The name of the collection to search.
151
+ # @param data [Array<Hash>] The data to search for.
152
+ # @param rerank [Hash] The rerank parameters.
153
+ # @param limit [Integer] The maximum number of results to return.
154
+ # @param output_fields [Array<String>] The fields to return in the results.
155
+ # @return [Hash] The search results.
156
+ def hybrid_search(
157
+ collection_name:,
158
+ search:,
159
+ rerank:,
160
+ limit: nil,
161
+ output_fields: []
162
+ )
163
+ response = client.connection.post("#{PATH}/hybrid_search") do |req|
164
+ params = {
165
+ collectionName: collection_name,
166
+ search: search,
167
+ rerank: rerank
168
+ }
169
+ params[:limit] = limit if limit
170
+ params[:outputFields] = output_fields if output_fields.any?
171
+ req.body = params
60
172
  end
61
173
  response.body.empty? ? true : response.body
62
174
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Milvus
4
+ class Indexes < Base
5
+ PATH = "indexes"
6
+
7
+ # This creates a named index for a target field, which can either be a vector field or a scalar field.
8
+ #
9
+ # @param collection_name [String] The name of the collection to create the index for.
10
+ # @param index_params [Hash] The parameters for the index.
11
+ # @return [Hash] Server response
12
+ def create(
13
+ collection_name:,
14
+ index_params:
15
+ )
16
+ response = client.connection.post("#{PATH}/create") do |req|
17
+ req.body = {
18
+ collectionName: collection_name,
19
+ indexParams: index_params
20
+ }.to_json
21
+ end
22
+ response.body.empty? ? true : response.body
23
+ end
24
+
25
+ # This operation deletes index from a specified collection.
26
+ #
27
+ # @param collection_name [String] The name of the collection to delete the index from.
28
+ # @param index_name [String] The name of the index to delete.
29
+ # @return [Hash] Server response
30
+ def drop(
31
+ collection_name:,
32
+ index_name:
33
+ )
34
+ response = client.connection.post("#{PATH}/drop") do |req|
35
+ req.body = {
36
+ collectionName: collection_name,
37
+ indexName: index_name
38
+ }.to_json
39
+ end
40
+ response.body.empty? ? true : response.body
41
+ end
42
+
43
+ # This operation describes the current index.
44
+ #
45
+ # @param collection_name [String] The name of the collection to describe the index for.
46
+ # @param index_name [String] The name of the index to describe.
47
+ # @return [Hash] Server response
48
+ def describe(
49
+ collection_name:,
50
+ index_name:
51
+ )
52
+ response = client.connection.post("#{PATH}/describe") do |req|
53
+ req.body = {
54
+ collectionName: collection_name,
55
+ indexName: index_name
56
+ }.to_json
57
+ end
58
+ response.body.empty? ? true : response.body
59
+ end
60
+
61
+ # This operation lists all indexes of a specific collection.
62
+ #
63
+ # @param collection_name [String] The name of the collection to list indexes for.
64
+ # @return [Hash] Server response
65
+ def list(
66
+ collection_name:
67
+ )
68
+ response = client.connection.post("#{PATH}/list") do |req|
69
+ req.body = {
70
+ collectionName: collection_name
71
+ }.to_json
72
+ end
73
+ response.body.empty? ? true : response.body
74
+ end
75
+ end
76
+ end
@@ -2,68 +2,104 @@
2
2
 
3
3
  module Milvus
4
4
  class Partitions < Base
5
- PATH = "partition"
5
+ PATH = "partitions"
6
6
 
7
- # Create a partition
7
+ # This operation lists all partitions in the database used in the current connection.
8
+ #
9
+ # @param collection_name [String] The name of the collection.
10
+ # @return [Hash] Server response
11
+ def list(collection_name:)
12
+ response = client.connection.post("#{PATH}/list") do |req|
13
+ req.body = {collectionName: collection_name}
14
+ end
15
+ response.body.empty? ? true : response.body
16
+ end
17
+
18
+ # This operation creates a partition in a collection.
19
+ #
20
+ # @param collection_name [String] The name of the collection to create the partition in.
21
+ # @param partition_name [String] The name of the partition to create.
8
22
  def create(collection_name:, partition_name:)
9
- response = client.connection.post(PATH) do |req|
23
+ response = client.connection.post("#{PATH}/create") do |req|
24
+ req.body = {
25
+ collectionName: collection_name,
26
+ partitionName: partition_name
27
+ }
28
+ end
29
+ response.body.empty? ? true : response.body
30
+ end
31
+
32
+ # This operation drops the current partition. To successfully drop a partition, ensure that the partition is already released.
33
+ #
34
+ # @param collection_name [String] The name of the collection to drop the partition from.
35
+ # @param partition_name [String] The name of the partition to drop.
36
+ # @return [Hash] Server response
37
+ def drop(collection_name:, partition_name:)
38
+ response = client.connection.post("#{PATH}/drop") do |req|
10
39
  req.body = {
11
- collection_name: collection_name,
12
- partition_name: partition_name
40
+ collectionName: collection_name,
41
+ partitionName: partition_name
13
42
  }
14
43
  end
15
44
  response.body.empty? ? true : response.body
16
45
  end
17
46
 
18
- # Verify if a partition exists
19
- def get(collection_name:, partition_name:)
20
- response = client.connection.get("#{PATH}/existence") do |req|
47
+ # This operation checks whether a partition exists.
48
+ #
49
+ # @param collection_name [String] The name of the collection to check for the partition in.
50
+ # @param partition_name [String] The name of the partition to check.
51
+ # @return [Hash] Server response
52
+ def has(collection_name:, partition_name:)
53
+ response = client.connection.post("#{PATH}/has") do |req|
21
54
  req.body = {
22
- collection_name: collection_name,
23
- partition_name: partition_name
55
+ collectionName: collection_name,
56
+ partitionName: partition_name
24
57
  }
25
58
  end
26
59
  response.body.empty? ? true : response.body
27
60
  end
28
61
 
29
- # Dropping a partition
30
- def delete(collection_name:, partition_name:)
31
- response = client.connection.delete(PATH) do |req|
62
+ # This operation loads the data of the current partition into memory.
63
+ #
64
+ # @param collection_name [String] The name of the collection to load.
65
+ # @param partition_names [Array<String>] The names of the partitions to load.
66
+ # @return [Hash] Server response
67
+ def load(collection_name:, partition_names:)
68
+ response = client.connection.post("#{PATH}/load") do |req|
32
69
  req.body = {
33
- collection_name: collection_name,
34
- partition_name: partition_name
70
+ collectionName: collection_name,
71
+ partitionNames: partition_names
35
72
  }
36
73
  end
37
74
  response.body.empty? ? true : response.body
38
75
  end
39
76
 
40
- # Load a Partition
41
- def load(
42
- collection_name:,
43
- partition_names:,
44
- replica_number: nil
45
- )
46
- response = client.connection.post("#{PATH}s/load") do |req|
77
+ # This operation releases the data of the current partition from memory.
78
+ #
79
+ # @param collection_name [String] The name of the collection to release.
80
+ # @param partition_name [String] The name of the partition to release.
81
+ # @return [Hash] Server response
82
+ def release(collection_name:, partition_names:)
83
+ response = client.connection.post("#{PATH}/release") do |req|
47
84
  req.body = {
48
- collection_name: collection_name,
49
- partition_names: partition_names
85
+ collectionName: collection_name,
86
+ partitionNames: partition_names
50
87
  }
51
- req.body[:replica_number] = replica_number if replica_number
52
88
  end
53
89
  response.body.empty? ? true : response.body
54
90
  end
55
91
 
56
- def release(
57
- collection_name:,
58
- partition_names:,
59
- replica_number: nil
60
- )
61
- response = client.connection.delete("#{PATH}s/load") do |req|
92
+ # This operations gets the number of entities in a partition.
93
+ #
94
+ # @param collection_name [String] The name of the collection to get the number of entities in.
95
+ # @param partition_name [String] The name of the partition to get the number of entities in.
96
+ # @return [Hash] Server response
97
+ def get_stats(collection_name:, partition_name:)
98
+ response = client.connection.post("#{PATH}/get_stats") do |req|
62
99
  req.body = {
63
- collection_name: collection_name,
64
- partition_names: partition_names
100
+ collectionName: collection_name,
101
+ partitionName: partition_name
65
102
  }
66
- req.body[:replica_number] = replica_number if replica_number
67
103
  end
68
104
  response.body.empty? ? true : response.body
69
105
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Milvus
4
- VERSION = "0.9.3"
4
+ VERSION = "0.10.0"
5
5
  end
data/lib/milvus.rb CHANGED
@@ -9,9 +9,6 @@ module Milvus
9
9
  autoload :Client, "milvus/client"
10
10
  autoload :Error, "milvus/error"
11
11
  autoload :Entities, "milvus/entities"
12
- autoload :Health, "milvus/health"
13
- autoload :Indices, "milvus/indices"
12
+ autoload :Indexes, "milvus/indexes"
14
13
  autoload :Partitions, "milvus/partitions"
15
- autoload :Search, "milvus/search"
16
- autoload :Query, "milvus/query"
17
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: milvus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Bondarev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-01 00:00:00.000000000 Z
11
+ date: 2024-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry-byebug
@@ -51,6 +51,7 @@ executables: []
51
51
  extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
+ - ".env.example"
54
55
  - ".rspec"
55
56
  - ".tool-versions"
56
57
  - CHANGELOG.md
@@ -66,11 +67,8 @@ files:
66
67
  - lib/milvus/constants.rb
67
68
  - lib/milvus/entities.rb
68
69
  - lib/milvus/error.rb
69
- - lib/milvus/health.rb
70
- - lib/milvus/indices.rb
70
+ - lib/milvus/indexes.rb
71
71
  - lib/milvus/partitions.rb
72
- - lib/milvus/query.rb
73
- - lib/milvus/search.rb
74
72
  - lib/milvus/version.rb
75
73
  - sig/milvus.rbs
76
74
  homepage: https://github.com/andreibondarev/milvus
data/lib/milvus/health.rb DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milvus
4
- class Health < Base
5
- PATH = "health"
6
-
7
- def get
8
- response = client.connection.get(PATH.to_s)
9
- response.body
10
- end
11
- end
12
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milvus
4
- class Indices < Base
5
- PATH = "index"
6
-
7
- def create(
8
- collection_name:,
9
- field_name:,
10
- extra_params:
11
- )
12
- response = client.connection.post(PATH) do |req|
13
- req.body = {
14
- collection_name: collection_name,
15
- field_name: field_name,
16
- extra_params: extra_params
17
- }.to_json
18
- end
19
- response.body.empty? ? true : response.body
20
- end
21
-
22
- def delete(
23
- collection_name:,
24
- field_name:
25
- )
26
- response = client.connection.delete(PATH) do |req|
27
- req.body = {
28
- collection_name: collection_name,
29
- field_name: field_name
30
- }.to_json
31
- end
32
- response.body.empty? ? true : response.body
33
- end
34
- end
35
- end
data/lib/milvus/query.rb DELETED
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milvus
4
- class Query < Base
5
- PATH = "query"
6
-
7
- def post(
8
- collection_name:,
9
- output_fields:,
10
- expr:
11
- )
12
- response = client.connection.post(PATH) do |req|
13
- req.body = {
14
- collection_name: collection_name,
15
- expr: expr
16
- }
17
- if output_fields
18
- req.body[:output_fields] = output_fields
19
- end
20
- end
21
- response.body.empty? ? true : response.body
22
- end
23
- end
24
- end
data/lib/milvus/search.rb DELETED
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Milvus
4
- class Search < Base
5
- PATH = "search"
6
-
7
- def post(
8
- collection_name:,
9
- anns_field:,
10
- top_k:,
11
- params:,
12
- metric_type:,
13
- vectors:,
14
- dsl_type:,
15
- output_fields: nil,
16
- round_decimal: nil,
17
- vector_type: nil
18
- )
19
- response = client.connection.post(PATH) do |req|
20
- req.body = {
21
- collection_name: collection_name,
22
- search_params: [
23
- {key: "anns_field", value: anns_field},
24
- {key: "topk", value: top_k},
25
- {key: "params", value: params},
26
- {key: "metric_type", value: metric_type}
27
- ],
28
- dsl_type: dsl_type,
29
- vectors: vectors,
30
- vector_type: vector_type
31
- }
32
- if round_decimal
33
- req.body[:search_params].push(
34
- {key: "round_decimal", value: round_decimal}
35
- )
36
- end
37
- if output_fields
38
- req.body[:output_fields] = output_fields
39
- end
40
- end
41
- response.body.empty? ? true : response.body
42
- end
43
- end
44
- end