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 <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
35 public:
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>
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>
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,
59 Options&&... options) const;
60
61 /// Inserts a single document into the collection
62 template <typename... Options>
63 WriteResult InsertOne(formats::bson::Document document, Options&&... options);
64
65 /// Inserts multiple documents into the collection
66 template <typename... Options>
67 WriteResult InsertMany(std::vector<formats::bson::Document> documents,
68 Options&&... options);
69
70 /// @brief Replaces a single matching document
71 /// @see options::Upsert
72 template <typename... Options>
73 WriteResult ReplaceOne(formats::bson::Document selector,
74 formats::bson::Document replacement,
75 Options&&... options);
76
77 /// @brief Updates a single matching document
78 /// @see options::Upsert
79 template <typename... Options>
80 WriteResult UpdateOne(formats::bson::Document selector,
81 formats::bson::Document update, Options&&... options);
82
83 /// @brief Updates all matching documents
84 /// @see options::Upsert
85 template <typename... Options>
86 WriteResult UpdateMany(formats::bson::Document selector,
87 formats::bson::Document update, Options&&... options);
88
89 /// Deletes a single matching document
90 template <typename... Options>
91 WriteResult DeleteOne(formats::bson::Document selector, Options&&... options);
92
93 /// Deletes all matching documents
94 template <typename... Options>
95 WriteResult DeleteMany(formats::bson::Document selector,
96 Options&&... options);
97
98 /// @brief Atomically updates a single matching document
99 /// @see options::ReturnNew
100 /// @see options::Upsert
101 template <typename... Options>
102 WriteResult FindAndModify(formats::bson::Document query,
103 const formats::bson::Document& update,
104 Options&&... options);
105
106 /// Atomically removes a single matching document
107 template <typename... Options>
108 WriteResult FindAndRemove(formats::bson::Document query,
109 Options&&... options);
110
111 /// Drop collection
112 template <typename... Options>
113 void Drop(Options&&... options);
114
115 /// Efficiently executes multiple operations in order, stops on error
116 template <typename... Options>
117 operations::Bulk MakeOrderedBulk(Options&&... options);
118
119 /// Efficiently executes multiple operations out of order, continues on error
120 template <typename... Options>
121 operations::Bulk MakeUnorderedBulk(Options&&... options);
122
123 /// @brief Executes an aggregation pipeline
124 /// @param pipeline an array of aggregation operations
125 template <typename... Options>
126 Cursor Aggregate(formats::bson::Value pipeline, Options&&... options);
127
128 /// Get collection name
129 const std::string& GetCollectionName() const;
130
131 /// @name Prepared operation executors
132 /// @{
133 size_t Execute(const operations::Count&) const;
134 size_t Execute(const operations::CountApprox&) const;
135 Cursor Execute(const operations::Find&) const;
136 WriteResult Execute(const operations::InsertOne&);
137 WriteResult Execute(const operations::InsertMany&);
138 WriteResult Execute(const operations::ReplaceOne&);
139 WriteResult Execute(const operations::Update&);
140 WriteResult Execute(const operations::Delete&);
141 WriteResult Execute(const operations::FindAndModify&);
142 WriteResult Execute(const operations::FindAndRemove&);
143 WriteResult Execute(operations::Bulk&&);
144 Cursor Execute(const operations::Aggregate&);
145 void Execute(const operations::Drop&);
146 /// @}
147 private:
148 std::shared_ptr<impl::CollectionImpl> impl_;
149};
150
151template <typename... Options>
153 Options&&... options) const {
154 operations::Count count_op(std::move(filter));
155 (count_op.SetOption(std::forward<Options>(options)), ...);
156 return Execute(count_op);
157}
158
159template <typename... Options>
161 operations::CountApprox count_approx_op;
162 (count_approx_op.SetOption(std::forward<Options>(options)), ...);
163 return Execute(count_approx_op);
164}
165
166namespace impl {
167
168template <typename Option, typename... Options>
169using HasOptionHelper =
170 std::disjunction<std::is_same<std::decay_t<Options>, Option>...>;
171
172template <typename Option, typename... Options>
173static constexpr bool kHasOption = HasOptionHelper<Option, Options...>::value;
174
175} // namespace impl
176
177template <typename... Options>
179 Options&&... options) const {
180 operations::Find find_op(std::move(filter));
181 (find_op.SetOption(std::forward<Options>(options)), ...);
182 return Execute(find_op);
183}
184
185template <typename... Options>
186std::optional<formats::bson::Document> Collection::FindOne(
187 formats::bson::Document filter, Options&&... options) const {
188 static_assert(
189 !(std::is_same<std::decay_t<Options>, options::Limit>::value || ...),
190 "Limit option cannot be used in FindOne");
191 auto cursor = Find(std::move(filter), options::Limit{1},
192 std::forward<Options>(options)...);
193 if (cursor.begin() == cursor.end()) return {};
194 return *cursor.begin();
195}
196
197template <typename... Options>
199 Options&&... options) {
200 operations::InsertOne insert_op(std::move(document));
201 (insert_op.SetOption(std::forward<Options>(options)), ...);
202 return Execute(insert_op);
203}
204
205template <typename... Options>
207 std::vector<formats::bson::Document> documents, Options&&... options) {
208 operations::InsertMany insert_op(std::move(documents));
209 (insert_op.SetOption(std::forward<Options>(options)), ...);
210 return Execute(insert_op);
211}
212
213template <typename... Options>
215 formats::bson::Document replacement,
216 Options&&... options) {
217 operations::ReplaceOne replace_op(std::move(selector),
218 std::move(replacement));
219 (replace_op.SetOption(std::forward<Options>(options)), ...);
220 return Execute(replace_op);
221}
222
223template <typename... Options>
225 formats::bson::Document update,
226 Options&&... options) {
227 operations::Update update_op(operations::Update::Mode::kSingle,
228 std::move(selector), std::move(update));
229 (update_op.SetOption(std::forward<Options>(options)), ...);
230 return Execute(update_op);
231}
232
233template <typename... Options>
235 formats::bson::Document update,
236 Options&&... options) {
237 operations::Update update_op(operations::Update::Mode::kMulti,
238 std::move(selector), std::move(update));
239 (update_op.SetOption(std::forward<Options>(options)), ...);
240 return Execute(update_op);
241}
242
243template <typename... Options>
245 Options&&... options) {
246 operations::Delete delete_op(operations::Delete::Mode::kSingle,
247 std::move(selector));
248 (delete_op.SetOption(std::forward<Options>(options)), ...);
249 return Execute(delete_op);
250}
251
252template <typename... Options>
254 Options&&... options) {
255 operations::Delete delete_op(operations::Delete::Mode::kMulti,
256 std::move(selector));
257 (delete_op.SetOption(std::forward<Options>(options)), ...);
258 return Execute(delete_op);
259}
260
261template <typename... Options>
263 const formats::bson::Document& update,
264 Options&&... options) {
265 operations::FindAndModify fam_op(std::move(query), update);
266 (fam_op.SetOption(std::forward<Options>(options)), ...);
267 return Execute(fam_op);
268}
269
270template <typename... Options>
272 Options&&... options) {
273 operations::FindAndRemove fam_op(std::move(query));
274 (fam_op.SetOption(std::forward<Options>(options)), ...);
275 return Execute(fam_op);
276}
277
278template <typename... Options>
279void Collection::Drop(Options&&... options) {
280 operations::Drop drop_op;
281 (drop_op.SetOption(std::forward<Options>(options)), ...);
282 return Execute(drop_op);
283}
284
285template <typename... Options>
286operations::Bulk Collection::MakeOrderedBulk(Options&&... options) {
287 operations::Bulk bulk(operations::Bulk::Mode::kOrdered);
288 (bulk.SetOption(std::forward<Options>(options)), ...);
289 return bulk;
290}
291
292template <typename... Options>
294 operations::Bulk bulk(operations::Bulk::Mode::kUnordered);
295 (bulk.SetOption(std::forward<Options>(options)), ...);
296 return bulk;
297}
298
299template <typename... Options>
301 Options&&... options) {
302 operations::Aggregate aggregate(std::move(pipeline));
303 (aggregate.SetOption(std::forward<Options>(options)), ...);
304 return Execute(aggregate);
305}
306
307} // namespace storages::mongo
308
309USERVER_NAMESPACE_END