Cppinecone
A C++ client for the Pinecone vector database
vector_types.hpp
Go to the documentation of this file.
1 #pragma once
7 #include <cstdint>
8 #include <optional>
9 #include <string>
10 #include <unordered_map>
11 #include <utility>
12 #include <variant>
13 #include <vector>
14 
15 #include <nlohmann/json.hpp>
16 
19 #include "pinecone/util/result.hpp"
20 
21 using json = nlohmann::json;
22 
23 namespace pinecone::types
24 {
28 struct index_stats {
30  [[nodiscard]] auto vector_count() const noexcept -> uint64_t { return vectorCount; }
31 
32  NLOHMANN_DEFINE_TYPE_INTRUSIVE(namespace_summary, vectorCount)
33 
34  private:
35  uint64_t vectorCount;
36  };
37 
38  NLOHMANN_DEFINE_TYPE_INTRUSIVE(index_stats, namespaces, dimension, indexFullness,
39  totalVectorCount)
40 
41  [[nodiscard]] auto stat_namespaces() const noexcept
42  -> std::unordered_map<std::string, namespace_summary> const&
43  {
44  return namespaces;
45  }
46 
47  [[nodiscard]] auto stat_dimension() const noexcept -> uint64_t { return dimension; }
48 
49  [[nodiscard]] auto stat_index_fullness() const noexcept -> double { return indexFullness; }
50 
51  [[nodiscard]] auto stat_total_vector_count() const noexcept -> uint64_t
52  {
53  return totalVectorCount;
54  }
55 
56  private:
58  uint64_t dimension;
59  double indexFullness;
60  uint64_t totalVectorCount;
61 };
62 
68 template <typename filter>
69 struct query {
70  struct builder {
71  builder(uint64_t top_k, std::vector<double> vector) noexcept
72  : _top_k(top_k), _query(std::move(vector)), _filter(filters::none())
73  {
74  }
75  builder(uint64_t top_k, std::string_view vector_id) noexcept
76  : _top_k(top_k), _query(vector_id), _filter(filters::none())
77  {
78  }
79  builder(filter f, uint64_t top_k, std::vector<double> vector) noexcept
80  : _top_k(top_k), _query(std::move(vector)), _filter(std::move(f))
81  {
82  }
83  builder(filter f, uint64_t top_k, std::string_view vector_id) noexcept
84  : _top_k(top_k), _query(vector_id), _filter(std::move(f))
85  {
86  }
87 
88  [[nodiscard]] auto with_namespace(std::string_view ns) noexcept -> builder&
89  {
90  _namespace = ns;
91  return *this;
92  }
93 
94  [[nodiscard]] auto with_include_values(bool inc) noexcept -> builder&
95  {
96  _include_values = inc;
97  return *this;
98  }
99 
100  [[nodiscard]] auto with_include_metadata(bool inc) noexcept -> builder&
101  {
102  _include_metadata = inc;
103  return *this;
104  }
105 
106  [[nodiscard]] auto build() const noexcept -> query
107  {
108  return query(_namespace, _top_k, _filter, _include_values, _include_metadata, _query);
109  }
110 
111  private:
112  uint64_t _top_k;
113  std::variant<std::vector<double>, std::string_view> _query;
114  filter _filter;
115  std::optional<std::string_view> _namespace;
116  std::optional<bool> _include_values;
117  std::optional<bool> _include_metadata;
118  };
119 
120  friend void to_json(nlohmann ::json& nlohmann_json_j, const query& nlohmann_json_t)
121  {
122  to_json(nlohmann_json_j["filter"], nlohmann_json_t._filter);
123  nlohmann_json_j["topK"] = nlohmann_json_t._top_k;
124 
125  if (std::holds_alternative<std::vector<double>>(nlohmann_json_t._query)) {
126  nlohmann_json_j["vector"] = std::get<std::vector<double>>(nlohmann_json_t._query);
127  } else if (std::holds_alternative<std::string_view>(nlohmann_json_t._query)) {
128  nlohmann_json_j["id"] = std::get<std::string_view>(nlohmann_json_t._query);
129  }
130 
131  if (nlohmann_json_t._namespace) {
132  nlohmann_json_j["namespace"] = *nlohmann_json_t._namespace;
133  }
134  if (nlohmann_json_t._include_values) {
135  nlohmann_json_j["includeValues"] = *nlohmann_json_t._include_values;
136  }
137  if (nlohmann_json_t._include_metadata) {
138  nlohmann_json_j["includeMetadata"] = *nlohmann_json_t._include_metadata;
139  }
140  }
141 
142  private:
143  uint64_t _top_k;
144  std::variant<std::vector<double>, std::string_view> _query;
145  std::optional<std::string_view> _namespace;
146  filter _filter;
147  std::optional<bool> _include_values;
148  std::optional<bool> _include_metadata;
149 
150  query(std::optional<std::string_view> ns, uint64_t top_k, filter f,
151  std::optional<bool> include_values, std::optional<bool> include_metadata,
152  std::variant<std::vector<double>, std::string_view> query) noexcept
153  : _top_k(top_k),
154  _query(std::move(query)),
155  _namespace(ns),
156  _filter(std::move(f)),
157  _include_values(include_values),
158  _include_metadata(include_metadata)
159  {
160  }
161 };
162 
170 inline auto query_builder(uint64_t top_k, std::vector<double> vector) noexcept
172 {
173  return {top_k, std::move(vector)};
174 }
175 
183 inline auto query_builder(uint64_t top_k, std::string_view vector_id) noexcept
185 {
186  return {top_k, vector_id};
187 }
188 
199 template <typename filter>
200 inline auto query_builder(filter f, uint64_t top_k, std::vector<double> vector) noexcept ->
201  typename query<filter>::builder
202 {
203  return {f, top_k, std::move(vector)};
204 }
205 
216 template <typename filter>
217 inline auto query_builder(filter f, uint64_t top_k, std::string_view vector_id) noexcept ->
218  typename query<filter>::builder
219 {
220  return {f, top_k, vector_id};
221 }
222 
227 struct query_result {
231  struct scored_vector {
232  [[nodiscard]] auto id() const noexcept -> std::string const& { return _id; }
233 
234  [[nodiscard]] auto score() const noexcept -> double { return _score; }
235 
236  [[nodiscard]] auto values() const noexcept -> std::optional<std::vector<double>> const&
237  {
238  return _values;
239  }
240 
241  [[nodiscard]] auto md() const noexcept -> std::optional<metadata> const& { return _metadata; }
242 
243  friend void from_json(const nlohmann ::json& nlohmann_json_j, scored_vector& nlohmann_json_t)
244  {
245  if (nlohmann_json_j.contains("values")) {
246  nlohmann_json_t._values = nlohmann_json_j["values"];
247  }
248 
249  if (nlohmann_json_j.contains("metadata")) {
250  metadata m;
251  from_json(nlohmann_json_j["metadata"], m);
252  nlohmann_json_t._metadata = std::move(m);
253  }
254 
255  nlohmann_json_j.at("id").get_to(nlohmann_json_t._id);
256  nlohmann_json_j.at("score").get_to(nlohmann_json_t._score);
257  }
258 
259  private:
260  std::string _id;
261  double _score;
262  std::optional<std::vector<double>> _values;
263  std::optional<metadata> _metadata;
264  };
265 
266  friend void from_json(const nlohmann ::json& nlohmann_json_j, query_result& nlohmann_json_t)
267  {
268  nlohmann_json_j.at("namespace").get_to(nlohmann_json_t._namespace);
269  nlohmann_json_j.at("matches").get_to(nlohmann_json_t.matches);
270  }
271 
272  [[nodiscard]] auto query_ns() const noexcept -> std::string const& { return _namespace; }
273 
274  [[nodiscard]] auto query_matches() const noexcept -> std::vector<scored_vector> const&
275  {
276  return matches;
277  }
278 
279  private:
280  std::string _namespace;
282 };
283 
285 
291 template <typename filter = no_filter>
293  using delete_mode = std::variant<ids, bool, filter>;
294 
295  struct builder {
296  explicit builder(ids ids) noexcept : _mode(std::move(ids)) {}
297  builder() noexcept : _mode(true) {}
298  explicit builder(filter f) noexcept : _mode(std::move(f)) {}
299 
300  [[nodiscard]] auto build() const noexcept -> delete_request
301  {
302  return delete_request(_mode, _namespace);
303  }
304 
305  auto with_namespace(std::string_view ns) noexcept -> builder&
306  {
307  _namespace = ns;
308  return *this;
309  }
310 
311  private:
312  delete_mode _mode;
313  std::optional<std::string_view> _namespace;
314  };
315 
316  friend void to_json(nlohmann ::json& nlohmann_json_j, const delete_request& nlohmann_json_t)
317  {
318  if (nlohmann_json_t._namespace) {
319  nlohmann_json_j["namespace"] = *nlohmann_json_t._namespace;
320  }
321 
322  if (std::holds_alternative<ids>(nlohmann_json_t._mode)) {
323  nlohmann_json_j["ids"] = json::array({});
324  for (auto const& id : std::get<ids>(nlohmann_json_t._mode)) {
325  nlohmann_json_j["ids"].emplace_back(id);
326  }
327  } else if (std::holds_alternative<bool>(nlohmann_json_t._mode)) {
328  nlohmann_json_j["deleteAll"] = std::get<bool>(nlohmann_json_t._mode);
329  } else if (std::holds_alternative<filter>(nlohmann_json_t._mode)) {
330  to_json(nlohmann_json_j, std::get<filter>(nlohmann_json_t._mode));
331  }
332  }
333 
334  private:
335  delete_mode _mode;
336  std::optional<std::string_view> _namespace;
337 
338  delete_request(delete_mode mode, std::optional<std::string_view> ns) noexcept
339  : _mode(std::move(mode)), _namespace(ns)
340  {
341  }
342 };
343 
347 struct vector {
348  vector() = default;
349  vector(std::string id, std::vector<double> values) noexcept
350  : _id(std::move(id)), _values(std::move(values)), _metadata(std::nullopt)
351  {
352  }
353 
354  vector(std::string id, std::vector<double> values, metadata md) noexcept
355  : _id(std::move(id)), _values(std::move(values)), _metadata(std::move(md))
356  {
357  }
358 
359  [[nodiscard]] auto id() const noexcept -> std::string const& { return _id; }
360 
361  [[nodiscard]] auto values() const noexcept -> std::vector<double> const& { return _values; }
362 
363  [[nodiscard]] auto md() const noexcept -> std::optional<metadata> const& { return _metadata; }
364 
365  friend void to_json(nlohmann ::json& nlohmann_json_j, const vector& nlohmann_json_t)
366  {
367  nlohmann_json_j["id"] = nlohmann_json_t._id;
368  nlohmann_json_j["values"] = nlohmann_json_t._values;
369  if (nlohmann_json_t._metadata) {
370  nlohmann_json_j["metadata"] = *nlohmann_json_t._metadata;
371  }
372  }
373 
374  friend void from_json(const nlohmann ::json& nlohmann_json_j, vector& nlohmann_json_t)
375  {
376  if (nlohmann_json_j.contains("metadata")) {
377  metadata m;
378  nlohmann_json_j.at("metadata").get_to(m);
379  nlohmann_json_t._metadata = std::move(m);
380  }
381 
382  nlohmann_json_j.at("values").get_to(nlohmann_json_t._values);
383  nlohmann_json_j.at("id").get_to(nlohmann_json_t._id);
384  }
385 
386  private:
387  std::string _id;
388  std::vector<double> _values;
389  std::optional<metadata> _metadata;
390 };
391 
396  struct builder {
397  explicit builder(std::vector<vector> vectors) noexcept : _vectors(std::move(vectors)) {}
398 
399  [[nodiscard]] auto build() const noexcept -> upsert_request { return {_vectors, _namespace}; }
400 
401  auto with_namespace(std::string_view ns) noexcept -> builder&
402  {
403  _namespace = ns;
404  return *this;
405  }
406 
407  private:
408  std::vector<vector> _vectors;
409  std::optional<std::string_view> _namespace;
410  };
411 
412  friend void to_json(nlohmann ::json& nlohmann_json_j, const upsert_request& nlohmann_json_t)
413  {
414  nlohmann_json_j["vectors"] = nlohmann_json_t._vectors;
415 
416  if (nlohmann_json_t._namespace) {
417  nlohmann_json_j["namespace"] = *nlohmann_json_t._namespace;
418  }
419  }
420 
421  private:
422  std::vector<vector> _vectors;
423  std::optional<std::string_view> _namespace;
424 
425  upsert_request(std::vector<vector> vectors, std::optional<std::string_view> ns) noexcept
426  : _vectors(std::move(vectors)), _namespace(ns)
427  {
428  }
429 };
430 
435  struct builder {
436  explicit builder(std::string_view id) noexcept : _id(id) {}
437 
438  [[nodiscard]] auto build() const noexcept -> update_request
439  {
440  return {_id, _values, _metadata, _namespace};
441  }
442 
443  auto with_namespace(std::string_view ns) noexcept -> builder&
444  {
445  _namespace = ns;
446  return *this;
447  }
448 
449  auto with_values(std::vector<double> values) noexcept -> builder&
450  {
451  _values = std::move(values);
452  return *this;
453  }
454 
455  auto with_metadata(metadata md) noexcept -> builder&
456  {
457  _metadata = md;
458  return *this;
459  }
460 
461  private:
462  std::string_view _id;
463  std::optional<std::vector<double>> _values;
464  std::optional<metadata> _metadata;
465  std::optional<std::string_view> _namespace;
466  };
467 
468  friend void to_json(nlohmann ::json& nlohmann_json_j, const update_request& nlohmann_json_t)
469  {
470  nlohmann_json_j["id"] = nlohmann_json_t._id;
471  if (nlohmann_json_t._values) {
472  nlohmann_json_j["values"] = *nlohmann_json_t._values;
473  }
474  if (nlohmann_json_t._metadata) {
475  to_json(nlohmann_json_j["setMetadata"], *nlohmann_json_t._metadata);
476  }
477  if (nlohmann_json_t._namespace) {
478  nlohmann_json_j["namespace"] = *nlohmann_json_t._namespace;
479  }
480  }
481 
482  private:
483  std::string_view _id;
484  std::optional<std::vector<double>> _values;
485  std::optional<metadata> _metadata;
486  std::optional<std::string_view> _namespace;
487 
488  update_request(std::string_view id, std::optional<std::vector<double>> values,
489  std::optional<metadata> md, std::optional<std::string_view> ns) noexcept
490  : _id(id), _values(std::move(values)), _metadata(std::move(md)), _namespace(ns)
491  {
492  }
493 };
494 } // namespace pinecone::types
T at(T... args)
Filters supported by complex vector API operations.
T move(T... args)
STL namespace.
Models the possibility of failure for Pinecone operations.
Deletes one or more vectors from an index.
Statistics for a Pinecone index.
Metadata for a single Pinecone vector.
A vector with its corresponding search score.
The result of a vector search.
A vector search.
Update existing vectors in an index.
Insert or update vectors in an index.
Representation of an individual Pinecone vector.
Encoding for Pinecone's vector metadata API.
auto query_builder(uint64_t top_k, std::vector< double > vector) noexcept -> query< no_filter >::builder
Construct a query builder given a number of results and a target vector.