MongoCollectionBase.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /* Copyright 2010-2017 MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Threading;
  19. using System.Threading.Tasks;
  20. using MongoDB.Bson;
  21. using MongoDB.Bson.Serialization;
  22. using MongoDB.Driver.Core.Misc;
  23. using MongoDB.Driver.Linq;
  24. namespace MongoDB.Driver
  25. {
  26. /// <summary>
  27. /// Base class for implementors of <see cref="IMongoCollection{TDocument}"/>.
  28. /// </summary>
  29. /// <typeparam name="TDocument">The type of the document.</typeparam>
  30. public abstract class MongoCollectionBase<TDocument> : IMongoCollection<TDocument>
  31. {
  32. /// <inheritdoc />
  33. public abstract CollectionNamespace CollectionNamespace { get; }
  34. /// <inheritdoc />
  35. public abstract IMongoDatabase Database { get; }
  36. /// <inheritdoc />
  37. public abstract IBsonSerializer<TDocument> DocumentSerializer { get; }
  38. /// <inheritdoc />
  39. public abstract IMongoIndexManager<TDocument> Indexes { get; }
  40. /// <inheritdoc />
  41. public abstract MongoCollectionSettings Settings { get; }
  42. /// <inheritdoc />
  43. public virtual IAsyncCursor<TResult> Aggregate<TResult>(PipelineDefinition<TDocument, TResult> pipeline, AggregateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  44. {
  45. throw new NotImplementedException();
  46. }
  47. /// <inheritdoc />
  48. public abstract Task<IAsyncCursor<TResult>> AggregateAsync<TResult>(PipelineDefinition<TDocument, TResult> pipeline, AggregateOptions options = null, CancellationToken cancellationToken = default(CancellationToken));
  49. /// <inheritdoc />
  50. public virtual BulkWriteResult<TDocument> BulkWrite(IEnumerable<WriteModel<TDocument>> requests, BulkWriteOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  51. {
  52. throw new NotImplementedException();
  53. }
  54. /// <inheritdoc />
  55. public abstract Task<BulkWriteResult<TDocument>> BulkWriteAsync(IEnumerable<WriteModel<TDocument>> requests, BulkWriteOptions options = null, CancellationToken cancellationToken = default(CancellationToken));
  56. /// <inheritdoc />
  57. public virtual long Count(FilterDefinition<TDocument> filter, CountOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  58. {
  59. throw new NotImplementedException();
  60. }
  61. /// <inheritdoc />
  62. public abstract Task<long> CountAsync(FilterDefinition<TDocument> filter, CountOptions options = null, CancellationToken cancellationToken = default(CancellationToken));
  63. /// <inheritdoc />
  64. public virtual DeleteResult DeleteMany(FilterDefinition<TDocument> filter, CancellationToken cancellationToken = default(CancellationToken))
  65. {
  66. return DeleteMany(filter, null, cancellationToken);
  67. }
  68. /// <inheritdoc />
  69. public virtual DeleteResult DeleteMany(FilterDefinition<TDocument> filter, DeleteOptions options, CancellationToken cancellationToken = default(CancellationToken))
  70. {
  71. Ensure.IsNotNull(filter, nameof(filter));
  72. options = options ?? new DeleteOptions();
  73. var model = new DeleteManyModel<TDocument>(filter)
  74. {
  75. Collation = options.Collation
  76. };
  77. try
  78. {
  79. var result = BulkWrite(new[] { model }, null, cancellationToken);
  80. return DeleteResult.FromCore(result);
  81. }
  82. catch (MongoBulkWriteException<TDocument> ex)
  83. {
  84. throw MongoWriteException.FromBulkWriteException(ex);
  85. }
  86. }
  87. /// <inheritdoc />
  88. public virtual Task<DeleteResult> DeleteManyAsync(FilterDefinition<TDocument> filter, CancellationToken cancellationToken = default(CancellationToken))
  89. {
  90. return DeleteManyAsync(filter, null, cancellationToken);
  91. }
  92. /// <inheritdoc />
  93. public virtual async Task<DeleteResult> DeleteManyAsync(FilterDefinition<TDocument> filter, DeleteOptions options, CancellationToken cancellationToken = default(CancellationToken))
  94. {
  95. Ensure.IsNotNull(filter, nameof(filter));
  96. options = options ?? new DeleteOptions();
  97. var model = new DeleteManyModel<TDocument>(filter)
  98. {
  99. Collation = options.Collation
  100. };
  101. try
  102. {
  103. var result = await BulkWriteAsync(new[] { model }, null, cancellationToken).ConfigureAwait(false);
  104. return DeleteResult.FromCore(result);
  105. }
  106. catch (MongoBulkWriteException<TDocument> ex)
  107. {
  108. throw MongoWriteException.FromBulkWriteException(ex);
  109. }
  110. }
  111. /// <inheritdoc />
  112. public virtual DeleteResult DeleteOne(FilterDefinition<TDocument> filter, CancellationToken cancellationToken = default(CancellationToken))
  113. {
  114. return DeleteOne(filter, null, cancellationToken);
  115. }
  116. /// <inheritdoc />
  117. public virtual DeleteResult DeleteOne(FilterDefinition<TDocument> filter, DeleteOptions options, CancellationToken cancellationToken = default(CancellationToken))
  118. {
  119. Ensure.IsNotNull(filter, nameof(filter));
  120. options = options ?? new DeleteOptions();
  121. var model = new DeleteOneModel<TDocument>(filter)
  122. {
  123. Collation = options.Collation
  124. };
  125. try
  126. {
  127. var result = BulkWrite(new[] { model }, null, cancellationToken);
  128. return DeleteResult.FromCore(result);
  129. }
  130. catch (MongoBulkWriteException<TDocument> ex)
  131. {
  132. throw MongoWriteException.FromBulkWriteException(ex);
  133. }
  134. }
  135. /// <inheritdoc />
  136. public virtual Task<DeleteResult> DeleteOneAsync(FilterDefinition<TDocument> filter, CancellationToken cancellationToken = default(CancellationToken))
  137. {
  138. return DeleteOneAsync(filter, null, cancellationToken);
  139. }
  140. /// <inheritdoc />
  141. public virtual async Task<DeleteResult> DeleteOneAsync(FilterDefinition<TDocument> filter, DeleteOptions options, CancellationToken cancellationToken = default(CancellationToken))
  142. {
  143. Ensure.IsNotNull(filter, nameof(filter));
  144. options = options ?? new DeleteOptions();
  145. var model = new DeleteOneModel<TDocument>(filter)
  146. {
  147. Collation = options.Collation
  148. };
  149. try
  150. {
  151. var result = await BulkWriteAsync(new[] { model }, null, cancellationToken).ConfigureAwait(false);
  152. return DeleteResult.FromCore(result);
  153. }
  154. catch (MongoBulkWriteException<TDocument> ex)
  155. {
  156. throw MongoWriteException.FromBulkWriteException(ex);
  157. }
  158. }
  159. /// <inheritdoc />
  160. public virtual IAsyncCursor<TField> Distinct<TField>(FieldDefinition<TDocument, TField> field, FilterDefinition<TDocument> filter, DistinctOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  161. {
  162. throw new NotImplementedException();
  163. }
  164. /// <inheritdoc />
  165. public abstract Task<IAsyncCursor<TField>> DistinctAsync<TField>(FieldDefinition<TDocument, TField> field, FilterDefinition<TDocument> filter, DistinctOptions options = null, CancellationToken cancellationToken = default(CancellationToken));
  166. /// <inheritdoc />
  167. public virtual IAsyncCursor<TProjection> FindSync<TProjection>(FilterDefinition<TDocument> filter, FindOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken))
  168. {
  169. throw new NotImplementedException();
  170. }
  171. /// <inheritdoc />
  172. public abstract Task<IAsyncCursor<TProjection>> FindAsync<TProjection>(FilterDefinition<TDocument> filter, FindOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken));
  173. /// <inheritdoc />
  174. public virtual TProjection FindOneAndDelete<TProjection>(FilterDefinition<TDocument> filter, FindOneAndDeleteOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken))
  175. {
  176. throw new NotImplementedException();
  177. }
  178. /// <inheritdoc />
  179. public abstract Task<TProjection> FindOneAndDeleteAsync<TProjection>(FilterDefinition<TDocument> filter, FindOneAndDeleteOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken));
  180. /// <inheritdoc />
  181. public virtual TProjection FindOneAndReplace<TProjection>(FilterDefinition<TDocument> filter, TDocument replacement, FindOneAndReplaceOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken))
  182. {
  183. throw new NotImplementedException();
  184. }
  185. /// <inheritdoc />
  186. public abstract Task<TProjection> FindOneAndReplaceAsync<TProjection>(FilterDefinition<TDocument> filter, TDocument replacement, FindOneAndReplaceOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken));
  187. /// <inheritdoc />
  188. public virtual TProjection FindOneAndUpdate<TProjection>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, FindOneAndUpdateOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken))
  189. {
  190. throw new NotImplementedException();
  191. }
  192. /// <inheritdoc />
  193. public abstract Task<TProjection> FindOneAndUpdateAsync<TProjection>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, FindOneAndUpdateOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken));
  194. /// <inheritdoc />
  195. public virtual void InsertOne(TDocument document, InsertOneOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  196. {
  197. Ensure.IsNotNull((object)document, "document");
  198. var model = new InsertOneModel<TDocument>(document);
  199. try
  200. {
  201. var bulkWriteOptions = options == null ? null : new BulkWriteOptions
  202. {
  203. BypassDocumentValidation = options.BypassDocumentValidation
  204. };
  205. BulkWrite(new[] { model }, bulkWriteOptions, cancellationToken);
  206. }
  207. catch (MongoBulkWriteException<TDocument> ex)
  208. {
  209. throw MongoWriteException.FromBulkWriteException(ex);
  210. }
  211. }
  212. /// <inheritdoc />
  213. [Obsolete("Use the new overload of InsertOneAsync with an InsertOneOptions parameter instead.")]
  214. public virtual Task InsertOneAsync(TDocument document, CancellationToken _cancellationToken)
  215. {
  216. return InsertOneAsync(document, null, _cancellationToken);
  217. }
  218. /// <inheritdoc />
  219. public virtual async Task InsertOneAsync(TDocument document, InsertOneOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  220. {
  221. Ensure.IsNotNull((object)document, "document");
  222. var model = new InsertOneModel<TDocument>(document);
  223. try
  224. {
  225. var bulkWriteOptions = options == null ? null : new BulkWriteOptions
  226. {
  227. BypassDocumentValidation = options.BypassDocumentValidation
  228. };
  229. await BulkWriteAsync(new[] { model }, bulkWriteOptions, cancellationToken).ConfigureAwait(false);
  230. }
  231. catch (MongoBulkWriteException<TDocument> ex)
  232. {
  233. throw MongoWriteException.FromBulkWriteException(ex);
  234. }
  235. }
  236. /// <inheritdoc />
  237. public virtual void InsertMany(IEnumerable<TDocument> documents, InsertManyOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  238. {
  239. Ensure.IsNotNull(documents, nameof(documents));
  240. var models = documents.Select(x => new InsertOneModel<TDocument>(x));
  241. BulkWriteOptions bulkWriteOptions = options == null ? null : new BulkWriteOptions
  242. {
  243. BypassDocumentValidation = options.BypassDocumentValidation,
  244. IsOrdered = options.IsOrdered
  245. };
  246. BulkWrite(models, bulkWriteOptions, cancellationToken);
  247. }
  248. /// <inheritdoc />
  249. public virtual Task InsertManyAsync(IEnumerable<TDocument> documents, InsertManyOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  250. {
  251. Ensure.IsNotNull(documents, nameof(documents));
  252. var models = documents.Select(x => new InsertOneModel<TDocument>(x));
  253. var bulkWriteOptions = options == null ? null : new BulkWriteOptions
  254. {
  255. BypassDocumentValidation = options.BypassDocumentValidation,
  256. IsOrdered = options.IsOrdered
  257. };
  258. return BulkWriteAsync(models, bulkWriteOptions, cancellationToken);
  259. }
  260. /// <inheritdoc />
  261. public virtual IAsyncCursor<TResult> MapReduce<TResult>(BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions<TDocument, TResult> options = null, CancellationToken cancellationToken = default(CancellationToken))
  262. {
  263. throw new NotImplementedException();
  264. }
  265. /// <inheritdoc />
  266. public abstract Task<IAsyncCursor<TResult>> MapReduceAsync<TResult>(BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions<TDocument, TResult> options = null, CancellationToken cancellationToken = default(CancellationToken));
  267. /// <inheritdoc />
  268. public abstract IFilteredMongoCollection<TDerivedDocument> OfType<TDerivedDocument>() where TDerivedDocument : TDocument;
  269. /// <inheritdoc />
  270. public virtual ReplaceOneResult ReplaceOne(FilterDefinition<TDocument> filter, TDocument replacement, UpdateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  271. {
  272. Ensure.IsNotNull(filter, nameof(filter));
  273. Ensure.IsNotNull((object)replacement, "replacement");
  274. if (options?.ArrayFilters != null)
  275. {
  276. throw new ArgumentException("ArrayFilters cannot be used with ReplaceOne.", nameof(options));
  277. }
  278. options = options ?? new UpdateOptions();
  279. var model = new ReplaceOneModel<TDocument>(filter, replacement)
  280. {
  281. Collation = options.Collation,
  282. IsUpsert = options.IsUpsert
  283. };
  284. try
  285. {
  286. var bulkWriteOptions = new BulkWriteOptions
  287. {
  288. BypassDocumentValidation = options.BypassDocumentValidation
  289. };
  290. var result = BulkWrite(new[] { model }, bulkWriteOptions, cancellationToken);
  291. return ReplaceOneResult.FromCore(result);
  292. }
  293. catch (MongoBulkWriteException<TDocument> ex)
  294. {
  295. throw MongoWriteException.FromBulkWriteException(ex);
  296. }
  297. }
  298. /// <inheritdoc />
  299. public virtual async Task<ReplaceOneResult> ReplaceOneAsync(FilterDefinition<TDocument> filter, TDocument replacement, UpdateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  300. {
  301. Ensure.IsNotNull(filter, nameof(filter));
  302. Ensure.IsNotNull((object)replacement, "replacement");
  303. if (options?.ArrayFilters != null)
  304. {
  305. throw new ArgumentException("ArrayFilters cannot be used with ReplaceOne.", nameof(options));
  306. }
  307. options = options ?? new UpdateOptions();
  308. var model = new ReplaceOneModel<TDocument>(filter, replacement)
  309. {
  310. Collation = options.Collation,
  311. IsUpsert = options.IsUpsert
  312. };
  313. try
  314. {
  315. var bulkWriteOptions = new BulkWriteOptions
  316. {
  317. BypassDocumentValidation = options.BypassDocumentValidation
  318. };
  319. var result = await BulkWriteAsync(new[] { model }, bulkWriteOptions, cancellationToken).ConfigureAwait(false);
  320. return ReplaceOneResult.FromCore(result);
  321. }
  322. catch (MongoBulkWriteException<TDocument> ex)
  323. {
  324. throw MongoWriteException.FromBulkWriteException(ex);
  325. }
  326. }
  327. /// <inheritdoc />
  328. public virtual UpdateResult UpdateMany(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, UpdateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  329. {
  330. Ensure.IsNotNull(filter, nameof(filter));
  331. Ensure.IsNotNull(update, nameof(update));
  332. options = options ?? new UpdateOptions();
  333. var model = new UpdateManyModel<TDocument>(filter, update)
  334. {
  335. ArrayFilters = options.ArrayFilters,
  336. Collation = options.Collation,
  337. IsUpsert = options.IsUpsert
  338. };
  339. try
  340. {
  341. var bulkWriteOptions = new BulkWriteOptions
  342. {
  343. BypassDocumentValidation = options.BypassDocumentValidation
  344. };
  345. var result = BulkWrite(new[] { model }, bulkWriteOptions, cancellationToken);
  346. return UpdateResult.FromCore(result);
  347. }
  348. catch (MongoBulkWriteException<TDocument> ex)
  349. {
  350. throw MongoWriteException.FromBulkWriteException(ex);
  351. }
  352. }
  353. /// <inheritdoc />
  354. public virtual async Task<UpdateResult> UpdateManyAsync(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, UpdateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  355. {
  356. Ensure.IsNotNull(filter, nameof(filter));
  357. Ensure.IsNotNull(update, nameof(update));
  358. options = options ?? new UpdateOptions();
  359. var model = new UpdateManyModel<TDocument>(filter, update)
  360. {
  361. ArrayFilters = options.ArrayFilters,
  362. Collation = options.Collation,
  363. IsUpsert = options.IsUpsert
  364. };
  365. try
  366. {
  367. var bulkWriteOptions = new BulkWriteOptions
  368. {
  369. BypassDocumentValidation = options.BypassDocumentValidation
  370. };
  371. var result = await BulkWriteAsync(new[] { model }, bulkWriteOptions, cancellationToken).ConfigureAwait(false);
  372. return UpdateResult.FromCore(result);
  373. }
  374. catch (MongoBulkWriteException<TDocument> ex)
  375. {
  376. throw MongoWriteException.FromBulkWriteException(ex);
  377. }
  378. }
  379. /// <inheritdoc />
  380. public virtual UpdateResult UpdateOne(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, UpdateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  381. {
  382. Ensure.IsNotNull(filter, nameof(filter));
  383. Ensure.IsNotNull(update, nameof(update));
  384. options = options ?? new UpdateOptions();
  385. var model = new UpdateOneModel<TDocument>(filter, update)
  386. {
  387. ArrayFilters = options.ArrayFilters,
  388. Collation = options.Collation,
  389. IsUpsert = options.IsUpsert
  390. };
  391. try
  392. {
  393. var bulkWriteOptions = new BulkWriteOptions
  394. {
  395. BypassDocumentValidation = options.BypassDocumentValidation
  396. };
  397. var result = BulkWrite(new[] { model }, bulkWriteOptions, cancellationToken);
  398. return UpdateResult.FromCore(result);
  399. }
  400. catch (MongoBulkWriteException<TDocument> ex)
  401. {
  402. throw MongoWriteException.FromBulkWriteException(ex);
  403. }
  404. }
  405. /// <inheritdoc />
  406. public virtual async Task<UpdateResult> UpdateOneAsync(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, UpdateOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
  407. {
  408. Ensure.IsNotNull(filter, nameof(filter));
  409. Ensure.IsNotNull(update, nameof(update));
  410. options = options ?? new UpdateOptions();
  411. var model = new UpdateOneModel<TDocument>(filter, update)
  412. {
  413. ArrayFilters = options.ArrayFilters,
  414. Collation = options.Collation,
  415. IsUpsert = options.IsUpsert
  416. };
  417. try
  418. {
  419. var bulkWriteOptions = new BulkWriteOptions
  420. {
  421. BypassDocumentValidation = options.BypassDocumentValidation
  422. };
  423. var result = await BulkWriteAsync(new[] { model }, bulkWriteOptions, cancellationToken).ConfigureAwait(false);
  424. return UpdateResult.FromCore(result);
  425. }
  426. catch (MongoBulkWriteException<TDocument> ex)
  427. {
  428. throw MongoWriteException.FromBulkWriteException(ex);
  429. }
  430. }
  431. /// <inheritdoc />
  432. public virtual IMongoCollection<TDocument> WithReadConcern(ReadConcern readConcern)
  433. {
  434. throw new NotImplementedException();
  435. }
  436. /// <inheritdoc />
  437. public abstract IMongoCollection<TDocument> WithReadPreference(ReadPreference readPreference);
  438. /// <inheritdoc />
  439. public abstract IMongoCollection<TDocument> WithWriteConcern(WriteConcern writeConcern);
  440. }
  441. }