userver: userver/storages/mongo/options.hpp Source File
Loading...
Searching...
No Matches
options.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/mongo/options.hpp
4/// @brief Query options
5
6#include <chrono>
7#include <cstddef>
8#include <cstdint>
9#include <initializer_list>
10#include <optional>
11#include <string>
12#include <string_view>
13#include <utility>
14#include <vector>
15
16#include <userver/formats/bson/bson_builder.hpp>
17#include <userver/formats/bson/document.hpp>
18#include <userver/formats/bson/value.hpp>
19
20USERVER_NAMESPACE_BEGIN
21
22/// Collection operation options
23namespace storages::mongo::options {
24
25/// @brief Read preference
26/// @see https://github.com/mongodb/mongo-c-driver/blob/master/src/libmongoc/doc/mongoc_read_prefs_t.rst
28public:
29 enum Mode {
30 /// Default mode. All operations read from the current replica set primary.
32 /// All operations read from among the nearest secondary members of the replica set.
34 /// In most situations, operations read from the primary but if it is unavailable, operations read from
35 /// secondary members.
37 /// In most situations, operations read from among the nearest secondary members, but if no secondaries are
38 /// available, operations read from the primary.
40 /// Operations read from among the nearest members of the replica set, irrespective of the member's type.
42 };
43
44 explicit ReadPreference(Mode mode);
45 ReadPreference(Mode mode, std::vector<formats::bson::Document> tags);
46
47 Mode GetMode() const;
48 std::optional<std::chrono::seconds> GetMaxStaleness() const;
49 const std::vector<formats::bson::Document>& GetTags() const;
50
51 /// @brief Sets maximum replication lag for eligible replica.
52 /// @note Must be at least 90 seconds, cannot be used with kPrimary mode.
53 ReadPreference& SetMaxStaleness(std::optional<std::chrono::seconds> max_staleness);
54
55 /// @brief Adds a tag to the tag set.
56 /// @note Cannot be used with kPrimary mode.
58
59private:
60 Mode mode_;
61 std::optional<std::chrono::seconds> max_staleness_;
62 std::vector<formats::bson::Document> tags_;
63};
64
65/// @brief Read concern
66/// @see https://docs.mongodb.org/manual/reference/readConcern/
67enum class ReadConcern {
68 /// no replication checks, default level
69 kLocal,
70 /// return data replicated to a majority of RS members
72 /// waits for all running majority writes to finish before read
74 /// no replication checks, may return orphaned documents if sharded; since 3.6
76};
77
78/// @brief Write concern
79/// @see https://docs.mongodb.org/manual/reference/write-concern/
81public:
82 enum Level {
83 /// Wait until propagation to a "majority" of RS nodes
85 /// Do not check for operation errors, do not wait for write, same as `0`
87 };
88
89 /// Default timeout for "majority" write concern
91
92 /// Creates a write concern with the special level
93 explicit WriteConcern(Level level);
94
95 /// Creates a write concern waiting for propagation to `nodes_count` RS nodes
96 explicit WriteConcern(size_t nodes_count);
97
98 /// Creates a write concern defined in RS config
99 explicit WriteConcern(std::string tag);
100
101 bool IsMajority() const;
102 size_t NodesCount() const;
103 const std::string& Tag() const;
104 std::optional<bool> Journal() const;
105 const std::chrono::milliseconds& Timeout() const;
106
107 /// Sets write concern timeout, `0` means no timeout
108 WriteConcern& SetTimeout(std::chrono::milliseconds timeout);
109
110 /// Sets whether to wait for on-disk journal commit
112
113private:
114 size_t nodes_count_;
115 bool is_majority_;
116 std::optional<bool> journal_;
117 std::string tag_;
118 std::chrono::milliseconds timeout_;
119};
120
121/// Disables ordering on bulk operations causing them to continue after an error
122class Unordered {};
123
124/// Enables insertion of a new document when update selector matches nothing
125class Upsert {};
126
127/// Enables automatic one-time retry of duplicate key errors
129
130/// Specifies that FindAndModify should return the new version of an object
131class ReturnNew {};
132
133/// Specifies the number of documents to skip
134class Skip {
135public:
136 explicit Skip(size_t value) : value_(value) {}
137
138 size_t Value() const { return value_; }
139
140 size_t value_;
141};
142
143/// @brief Specifies the number of documents to request from the server
144/// @note The value of `0` means "no limit".
145class Limit {
146public:
147 explicit Limit(size_t value) : value_(value) {}
148
149 size_t Value() const { return value_; }
150
151private:
152 size_t value_;
153};
154
155/// @brief Selects fields to be returned
156/// @note `_id` field is always included by default, order might be significant
157/// @see
158/// https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/
160public:
161 /// Creates a default projection including all fields
162 Projection() = default;
163
164 /// Creates a projection including only specified fields
165 Projection(std::initializer_list<std::string_view> fields_to_include);
166
167 /// Includes a field into the projection
168 Projection& Include(std::string_view field);
169
170 /// @brief Excludes a field from the projection
171 /// @warning Projection cannot have a mix of inclusion and exclusion.
172 /// Only the `_id` field can always be excluded.
173 Projection& Exclude(std::string_view field);
174
175 /// @brief Setups an array slice in the projection
176 /// @param field name of the array field to slice
177 /// @param limit the number of items to return
178 /// @param skip the following number of items
179 /// @note `skip` can be negative, this corresponds to counting from the end
180 /// backwards.
181 /// @note `limit < 0, skip == 0` is equivalent to `limit' = -limit, skip' =
182 /// limit`.
183 /// @warning Cannot be applied to views.
184 Projection& Slice(std::string_view field, int32_t limit, int32_t skip = 0);
185
186 /// @brief Matches the first element of an array satisfying a predicate
187 /// @param field name of the array to search
188 /// @param pred predicate to apply to elements
189 /// @note Array field will be absent from the result if no elements match.
190 /// @note Empty document as a predicate will only match empty documents.
191 Projection& ElemMatch(std::string_view field, const formats::bson::Document& pred);
192
193 /// @cond
194 /// Projection specification BSON access
195 const bson_t* GetProjectionBson() const;
196 /// @endcond
197
198private:
199 formats::bson::impl::BsonBuilder projection_builder_;
200};
201
202/// Sorts the results
203class Sort {
204public:
205 enum Direction {
206 kAscending,
207 kDescending,
208 };
209
210 /// Creates an empty ordering specification
211 Sort() = default;
212
213 /// Stores the specified ordering specification
215
216 /// Appends a field to the ordering specification
217 Sort& By(std::string_view field, Direction direction);
218
219 /// @cond
220 /// Sort specification BSON access
221 const bson_t* GetSortBson() const;
222 /// @endcond
223
224private:
225 formats::bson::impl::BsonBuilder sort_builder_;
226};
227
228/// @brief Specifies an index to use for the query
229/// @warning Only plans using the index will be considered.
230class Hint {
231public:
232 /// Specifies an index by name
233 explicit Hint(std::string index_name);
234
235 /// Specifies an index by fields covered
236 explicit Hint(formats::bson::Document index_spec);
237
238 /// @cond
239 /// Retrieves a hint value
240 const formats::bson::Value& Value() const;
241 /// @endcond
242
243private:
244 formats::bson::Value value_;
245};
246
247/// @brief Specifies an array of filter documents that
248/// determine which array elements to modify for an update
249/// operation on an array field.
251public:
252 /// Specifies list of filters
253 explicit ArrayFilters(std::initializer_list<formats::bson::Document>);
254
255 /// @cond
256 /// Retrieves an arrayFilters value
257 const formats::bson::Value& Value() const;
258 /// @endcond
259
260private:
261 formats::bson::Value value_;
262};
263
264/// Selects count implementation to use: new aggregation-based or old cmd-based
265enum class ForceCountImpl { kAggregate, kCmd };
266
267/// Suppresses errors on querying a sharded collection with unavailable shards
269
270/// @brief Disables exception throw on server errors, should be checked manually
271/// in WriteResult
273
274/// @brief Enables tailable cursor, which block at the end of capped collections
275/// @note Automatically sets `awaitData`.
276/// @see https://docs.mongodb.com/manual/core/tailable-cursors/
277class Tailable {};
278
279/// Sets a comment for the operation, which would be visible in profile data
280class Comment {
281public:
282 explicit Comment(std::string);
283
284 const std::string& Value() const;
285
286private:
287 std::string value_;
288};
289
290/// @brief Specifies the server-side time limit for the operation
291/// @warning This does not set any client-side timeouts.
293public:
294 explicit MaxServerTime(const std::chrono::milliseconds& value) : value_(value) {}
295
296 const std::chrono::milliseconds& Value() const { return value_; }
297
298private:
299 std::chrono::milliseconds value_;
300};
301
302} // namespace storages::mongo::options
303
304USERVER_NAMESPACE_END