userver: userver/storages/mongo/collection.hpp Source File
Loading...
Searching...
No Matches
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