userver: userver/storages/mongo/collection.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
collection.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/mongo/collection.hpp
4/// @brief @copybrief storages::mongo::Collection
5
6#include <memory>
7#include <optional>
8#include <type_traits>
9#include <vector>
10
11#include <userver/formats/bson/document.hpp>
12#include <userver/formats/bson/value.hpp>
13#include <userver/storages/mongo/bulk.hpp>
14#include <userver/storages/mongo/cursor.hpp>
15#include <userver/storages/mongo/operations.hpp>
16#include <userver/storages/mongo/write_result.hpp>
17
18USERVER_NAMESPACE_BEGIN
19
20namespace storages::mongo {
21
22namespace impl {
23class CollectionImpl;
24} // namespace impl
25
26/// @brief MongoDB collection handle, the main way to operate with MongoDB.
27///
28/// Usually retrieved from storages::mongo::Pool
29///
30/// ## Example:
31///
32/// @snippet storages/mongo/collection_mongotest.hpp Sample Mongo usage
34 public:
35 /// @cond
36 // For internal use only.
37 explicit Collection(std::shared_ptr<impl::CollectionImpl>);
38 /// @endcond
39
40 /// @brief Returns the number of documents matching the query
41 /// @warning Unless explicitly overridden, runs CountApprox for empty filters
42 /// @see options::ForceCountImpl
43 template <typename... Options>
45
46 /// @brief Returns an approximated count of all documents in the collection
47 /// @note This method uses collection metadata and should be faster
48 template <typename... Options>
50
51 /// Performs a query on the collection
52 template <typename... Options>
53 Cursor Find(formats::bson::Document filter, Options&&... options) const;
54
55 /// Retrieves a single document from the collection
56 template <typename... Options>
57 std::optional<formats::bson::Document> FindOne(formats::bson::Document filter,
58 Options&&... options) const;
59
60 /// Inserts a single document into the collection
61 template <typename... Options>
62 WriteResult InsertOne(formats::bson::Document document, Options&&... options);
63
64 /// Inserts multiple documents into the collection
65 template <typename... Options>
66 WriteResult InsertMany(std::vector<formats::bson::Document> documents,
67 Options&&... options);
68
69 /// @brief Replaces a single matching document
70 /// @see options::Upsert
71 template <typename... Options>
72 WriteResult ReplaceOne(formats::bson::Document selector,
73 formats::bson::Document replacement,
74 Options&&... options);
75
76 /// @brief Updates a single matching document
77 /// @see options::Upsert
78 template <typename... Options>
79 WriteResult UpdateOne(formats::bson::Document selector,
80 formats::bson::Document update, Options&&... options);
81
82 /// @brief Updates all matching documents
83 /// @see options::Upsert
84 template <typename... Options>
85 WriteResult UpdateMany(formats::bson::Document selector,
86 formats::bson::Document update, Options&&... options);
87
88 /// Deletes a single matching document
89 template <typename... Options>
90 WriteResult DeleteOne(formats::bson::Document selector, Options&&... options);
91
92 /// Deletes all matching documents
93 template <typename... Options>
94 WriteResult DeleteMany(formats::bson::Document selector,
95 Options&&... options);
96
97 /// @brief Atomically updates a single matching document
98 /// @see options::ReturnNew
99 /// @see options::Upsert
100 template <typename... Options>
101 WriteResult FindAndModify(formats::bson::Document query,
102 const formats::bson::Document& update,
103 Options&&... options);
104
105 /// Atomically removes a single matching document
106 template <typename... Options>
107 WriteResult FindAndRemove(formats::bson::Document query,
108 Options&&... options);
109
110 /// Drop collection
111 template <typename... Options>
112 void Drop(Options&&... options);
113
114 /// Efficiently executes multiple operations in order, stops on error
115 template <typename... Options>
116 operations::Bulk MakeOrderedBulk(Options&&... options);
117
118 /// Efficiently executes multiple operations out of order, continues on error
119 template <typename... Options>
120 operations::Bulk MakeUnorderedBulk(Options&&... options);
121
122 /// @brief Executes an aggregation pipeline
123 /// @param pipeline an array of aggregation operations
124 template <typename... Options>
125 Cursor Aggregate(formats::bson::Value pipeline, Options&&... options);
126
127 /// @name Prepared operation executors
128 /// @{
129 size_t Execute(const operations::Count&) const;
130 size_t Execute(const operations::CountApprox&) const;
131 Cursor Execute(const operations::Find&) const;
132 WriteResult Execute(const operations::InsertOne&);
133 WriteResult Execute(const operations::InsertMany&);
134 WriteResult Execute(const operations::ReplaceOne&);
135 WriteResult Execute(const operations::Update&);
136 WriteResult Execute(const operations::Delete&);
137 WriteResult Execute(const operations::FindAndModify&);
138 WriteResult Execute(const operations::FindAndRemove&);
139 WriteResult Execute(operations::Bulk&&);
140 Cursor Execute(const operations::Aggregate&);
141 void Execute(const operations::Drop&);
142 /// @}
143 private:
144 std::shared_ptr<impl::CollectionImpl> impl_;
145};
146
147template <typename... Options>
149 Options&&... options) const {
150 operations::Count count_op(std::move(filter));
151 (count_op.SetOption(std::forward<Options>(options)), ...);
152 return Execute(count_op);
153}
154
155template <typename... Options>
157 operations::CountApprox count_approx_op;
158 (count_approx_op.SetOption(std::forward<Options>(options)), ...);
159 return Execute(count_approx_op);
160}
161
162namespace impl {
163
164template <typename Option, typename... Options>
165using HasOptionHelper =
166 std::disjunction<std::is_same<std::decay_t<Options>, Option>...>;
167
168template <typename Option, typename... Options>
169static constexpr bool kHasOption = HasOptionHelper<Option, Options...>::value;
170
171} // namespace impl
172
173template <typename... Options>
175 Options&&... options) const {
176 operations::Find find_op(std::move(filter));
177 (find_op.SetOption(std::forward<Options>(options)), ...);
178 return Execute(find_op);
179}
180
181template <typename... Options>
182std::optional<formats::bson::Document> Collection::FindOne(
183 formats::bson::Document filter, Options&&... options) const {
184 static_assert(
185 !(std::is_same<std::decay_t<Options>, options::Limit>::value || ...),
186 "Limit option cannot be used in FindOne");
187 auto cursor = Find(std::move(filter), options::Limit{1},
188 std::forward<Options>(options)...);
189 if (cursor.begin() == cursor.end()) return {};
190 return *cursor.begin();
191}
192
193template <typename... Options>
195 Options&&... options) {
196 operations::InsertOne insert_op(std::move(document));
197 (insert_op.SetOption(std::forward<Options>(options)), ...);
198 return Execute(insert_op);
199}
200
201template <typename... Options>
203 std::vector<formats::bson::Document> documents, Options&&... options) {
204 operations::InsertMany insert_op(std::move(documents));
205 (insert_op.SetOption(std::forward<Options>(options)), ...);
206 return Execute(insert_op);
207}
208
209template <typename... Options>
211 formats::bson::Document replacement,
212 Options&&... options) {
213 operations::ReplaceOne replace_op(std::move(selector),
214 std::move(replacement));
215 (replace_op.SetOption(std::forward<Options>(options)), ...);
216 return Execute(replace_op);
217}
218
219template <typename... Options>
221 formats::bson::Document update,
222 Options&&... options) {
223 operations::Update update_op(operations::Update::Mode::kSingle,
224 std::move(selector), std::move(update));
225 (update_op.SetOption(std::forward<Options>(options)), ...);
226 return Execute(update_op);
227}
228
229template <typename... Options>
231 formats::bson::Document update,
232 Options&&... options) {
233 operations::Update update_op(operations::Update::Mode::kMulti,
234 std::move(selector), std::move(update));
235 (update_op.SetOption(std::forward<Options>(options)), ...);
236 return Execute(update_op);
237}
238
239template <typename... Options>
241 Options&&... options) {
242 operations::Delete delete_op(operations::Delete::Mode::kSingle,
243 std::move(selector));
244 (delete_op.SetOption(std::forward<Options>(options)), ...);
245 return Execute(delete_op);
246}
247
248template <typename... Options>
250 Options&&... options) {
251 operations::Delete delete_op(operations::Delete::Mode::kMulti,
252 std::move(selector));
253 (delete_op.SetOption(std::forward<Options>(options)), ...);
254 return Execute(delete_op);
255}
256
257template <typename... Options>
259 const formats::bson::Document& update,
260 Options&&... options) {
261 operations::FindAndModify fam_op(std::move(query), update);
262 (fam_op.SetOption(std::forward<Options>(options)), ...);
263 return Execute(fam_op);
264}
265
266template <typename... Options>
268 Options&&... options) {
269 operations::FindAndRemove fam_op(std::move(query));
270 (fam_op.SetOption(std::forward<Options>(options)), ...);
271 return Execute(fam_op);
272}
273
274template <typename... Options>
275void Collection::Drop(Options&&... options) {
276 operations::Drop drop_op;
277 (drop_op.SetOption(std::forward<Options>(options)), ...);
278 return Execute(drop_op);
279}
280
281template <typename... Options>
282operations::Bulk Collection::MakeOrderedBulk(Options&&... options) {
283 operations::Bulk bulk(operations::Bulk::Mode::kOrdered);
284 (bulk.SetOption(std::forward<Options>(options)), ...);
285 return bulk;
286}
287
288template <typename... Options>
290 operations::Bulk bulk(operations::Bulk::Mode::kUnordered);
291 (bulk.SetOption(std::forward<Options>(options)), ...);
292 return bulk;
293}
294
295template <typename... Options>
297 Options&&... options) {
298 operations::Aggregate aggregate(std::move(pipeline));
299 (aggregate.SetOption(std::forward<Options>(options)), ...);
300 return Execute(aggregate);
301}
302
303} // namespace storages::mongo
304
305USERVER_NAMESPACE_END