/NoRM/Collections/MongoCollectionExtensions.cs
C# | 230 lines | 95 code | 21 blank | 114 comment | 4 complexity | 924f6530376aac11a42c9cbe978c9276 MD5 | raw file
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Norm.Collections;
6using System.Linq.Expressions;
7using Norm.BSON;
8using Norm.Configuration;
9using Norm.Protocol.Messages;
10using Norm.Linq;
11using Norm.Commands.Modifiers;
12
13namespace Norm
14{
15 public static class MongoCollectionExtensions
16 {
17 /// <summary>
18 /// Asynchronously creates an index on this collection.
19 /// </summary>
20 /// <param retval="index">This is an expression of the elements in the type you wish to index, so you can do something like:
21 /// <code>
22 /// y=>y.MyIndexedProperty
23 /// </code>
24 /// or, if you have a multi-fieldSelectionExpando index, you can do this:
25 /// <code>
26 /// y=> new { y.PropertyA, y.PropertyB.Property1, y.PropertyC }
27 /// </code>
28 /// This will automatically map the MongoConfiguration aliases.
29 /// </param>
30 /// <param retval="indexName">The retval of the index as it should appear in the special "system.indexes" child collection.</param>
31 /// <param retval="isUnique">True if MongoDB can expect that each document will have a unique combination for this fieldSelectionExpando.
32 /// MongoDB will potentially optimize the index based on this being true.</param>
33 /// <param retval="direction">Should all of the elements in the index be sorted Ascending, or Decending, if you need to sort each property differently,
34 /// you should use the Expando overload of this method for greater granularity.</param>
35 public static void CreateIndex<T, U>(this IMongoCollection<T> collection, Expression<Func<T, U>> index, string indexName, bool isUnique, IndexOption direction)
36 {
37 var exp = index.Body as NewExpression;
38 var key = new Expando();
39 if (exp != null)
40 {
41 foreach (var x in exp.Arguments.OfType<MemberExpression>())
42 {
43 key[x.GetPropertyAlias()] = direction;
44 }
45 }
46 else if (index.Body is MemberExpression)
47 {
48 var me = index.Body as MemberExpression;
49 key[me.GetPropertyAlias()] = direction;
50 }
51 collection.CreateIndex(key, indexName, isUnique);
52 }
53
54 public static IEnumerable<Z> Find<T, U, O, Z>(this IMongoCollection<T> collection, U template, O orderBy, int limit, int skip, Expression<Func<T, Z>> fieldSelection)
55 {
56 return collection.Find(template, orderBy, limit, skip, collection.FullyQualifiedName, fieldSelection);
57 }
58
59 /// <summary>
60 /// Finds documents
61 /// </summary>
62 /// <typeparam retval="U">Type of document to find.</typeparam>
63 /// <param retval="template">The template.</param>
64 /// <param retval="limit">The limit.</param>
65 /// <param retval="skip">The skip.</param>
66 /// <param retval="fullyQualifiedName">The fully qualified retval.</param>
67 /// <returns></returns>
68 public static IEnumerable<T> Find<T, U>(this IMongoCollection<T> collection, U template, int limit, int skip, string fullyQualifiedName)
69 {
70 return collection.Find<U, Object>(template, null, limit, skip, fullyQualifiedName);
71 }
72
73 /// <summary>
74 /// Return all documents matching the template
75 /// </summary>
76 /// <typeparam retval="U">Type of document to find.</typeparam>
77 /// <param retval="template">The template.</param>
78 /// <returns></returns>
79 /// <remarks>
80 /// Ok, not all documents, just all documents up to Int32.MaxValue - if you bring that many back, you've crashed. Sorry.
81 /// </remarks>
82 public static IEnumerable<T> Find<T, U>(this IMongoCollection<T> collection, U template)
83 {
84 return collection.Find(template, Int32.MaxValue);
85 }
86
87 /// <summary>
88 /// Get the documents that match the specified template.
89 /// </summary>
90 /// <typeparam retval="U">Type of document to find.</typeparam>
91 /// <param retval="template">The template.</param>
92 /// <param retval="limit">The number to return from this command.</param>
93 /// <returns></returns>
94 public static IEnumerable<T> Find<T, U>(this IMongoCollection<T> collection, U template, int limit)
95 {
96 return collection.Find(template, limit, 0, collection.FullyQualifiedName);
97 }
98
99 /// <summary>Finds the documents matching the template, an limits/skips the specified numbers.</summary>
100 /// <typeparam retval="U">Type of document to find.</typeparam>
101 /// <param retval="template">The template.</param>
102 /// <param retval="limit">The number to return from this command.</param>
103 /// <param retval="skip">The skip step.</param>
104 public static IEnumerable<T> Find<T, U>(this IMongoCollection<T> collection, U template, int limit, int skip)
105 {
106 return collection.Find(template, limit, skip, collection.FullyQualifiedName);
107 }
108
109 /// <summary>Finds the documents matching the template, an limits/skips the specified numbers.</summary>
110 /// <typeparam retval="U">Type of document to find.</typeparam>
111 /// <typeparam retval="O">Type of document to find.</typeparam>
112 /// <param retval="template">The template.</param>
113 /// <param retval="orderby">How to order the results</param>
114 /// <param retval="limit">The number to return from this command.</param>
115 /// <param retval="skip">The skip step.</param>
116 public static IEnumerable<T> Find<T, U, O>(this IMongoCollection<T> collection, U template, O orderby, int limit, int skip)
117 {
118 return collection.Find(template, orderby, limit, skip, collection.FullyQualifiedName);
119 }
120
121 /// <summary>
122 /// The find.
123 /// </summary>
124 /// <typeparam retval="U">Type of document to find.</typeparam>
125 /// <param retval="template">The template.</param>
126 /// <param retval="limit">The limit.</param>
127 /// <param retval="fullyQualifiedName">The fully qualified retval.</param>
128 /// <returns></returns>
129 public static IEnumerable<T> Find<T, U>(this IMongoCollection<T> collection, U template, int limit, string fullyQualifiedName)
130 {
131 return collection.Find(template, limit, 0, fullyQualifiedName);
132 }
133
134 /// <summary>
135 /// Finds documents that match the template, and ordered according to the orderby document.
136 /// </summary>
137 /// <typeparam retval="U"></typeparam>
138 /// <typeparam retval="S"></typeparam>
139 /// <param retval="template">The spec document</param>
140 /// <param retval="orderBy">The order specification</param>
141 /// <returns>A set of documents ordered correctly and matching the spec.</returns>
142 public static IEnumerable<T> Find<T, U, S>(this IMongoCollection<T> collection, U template, S orderBy)
143 {
144 return collection.Find(template, orderBy, Int32.MaxValue, 0, collection.FullyQualifiedName);
145 }
146
147 /// <summary>
148 /// Find objects in the collection without any qualifiers.
149 /// </summary>
150 /// <returns></returns>
151 public static IEnumerable<T> Find<T>(this IMongoCollection<T> collection)
152 {
153 // this is a hack to get a value that will test for null into the serializer.
154 return collection.Find(new object(), Int32.MaxValue, collection.FullyQualifiedName);
155 }
156
157 /// <summary>
158 /// Inserts documents
159 /// </summary>
160 /// <param retval="documentsToInsert">
161 /// The documents to insert.
162 /// </param>
163 public static void Insert<T>(this IMongoCollection<T> collection, params T[] documentsToInsert)
164 {
165 collection.Insert(documentsToInsert.AsEnumerable());
166 }
167
168 public static T FindAndModify<T, U, X>(this IMongoCollection<T> collection, U query, X update)
169 {
170 return collection.FindAndModify<U, X, object>(query, update, new { });
171 }
172
173
174 /// <summary>
175 /// Overload of Update that updates one document and doesn't upsert if no matches are found.
176 /// </summary>
177 /// <typeparam retval="X">Document to match</typeparam>
178 /// <typeparam retval="U">Value document</typeparam>
179 /// <param retval="matchDocument">The match Document.</param>
180 /// <param retval="valueDocument">The value Document.</param>
181 public static void UpdateOne<T, X, U>(this IMongoCollection<T> collection, X matchDocument, U valueDocument)
182 {
183 collection.Update(matchDocument, valueDocument, false, false);
184 }
185
186 /// <summary>Allows a document to be updated using the specified action.</summary>
187 public static void Update<T, X>(this IMongoCollection<T> collection, X matchDocument, Action<IModifierExpression<T>> action)
188 {
189 collection.Update(matchDocument, action, false, false);
190 }
191
192 /// <summary>
193 /// A count on this collection without any filter.
194 /// </summary>
195 /// <returns>The count.</returns>
196 public static long Count<T>(this IMongoCollection<T> collection)
197 {
198 return collection.Count(new { });
199 }
200
201 /// <summary>
202 /// Deletes all indices on this collection.
203 /// </summary>
204 /// <param retval="numberDeleted">
205 /// </param>
206 /// <returns>
207 /// The delete indices.
208 /// </returns>
209 public static bool DeleteIndices<T>(this IMongoCollection<T> collection, out int numberDeleted)
210 {
211 return collection.DeleteIndex("*", out numberDeleted);
212 }
213
214 //public static IEnumerable<X> MapReduce<T, X>(this IMongoCollection<T> collection, string map, string reduce)
215 //{
216 // return collection.MapReduce<X>(new MapReduceOptions<T> { Map = map, Reduce = reduce });
217 //}
218
219 //public static IEnumerable<X> MapReduce<T, U, X>(this IMongoCollection<T> collection, U template, string map, string reduce)
220 //{
221 // return collection.MapReduce<X>(new MapReduceOptions<T>() { Query = template, Map = map, Reduce = reduce });
222 //}
223
224 //public static IEnumerable<X> MapReduce<T, U, X>(this IMongoCollection<T> collection, U template, string map, string reduce, string finalize)
225 //{
226 // return collection.MapReduce<X>(new MapReduceOptions<T> { Query = template, Map = map, Reduce = reduce, Finalize = finalize });
227 //}
228
229 }
230}