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