milvus 0.9.3 β†’ 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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