PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/MongoDB.Driver.Tests/Samples/AggregationSample.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 220 lines | 174 code | 31 blank | 15 comment | 1 complexity | 5d4f8c599b85a01a9639a2965efba054 MD5 | raw file
Possible License(s): Apache-2.0
  1. /* Copyright 2010-present 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.Linq;
  16. using System.Threading.Tasks;
  17. using FluentAssertions;
  18. using MongoDB.Bson.Serialization.Attributes;
  19. using MongoDB.Driver.Linq;
  20. using Xunit;
  21. namespace MongoDB.Driver.Tests.Samples
  22. {
  23. public class AggregationSample
  24. {
  25. private static IMongoCollection<ZipEntry> __collection;
  26. private static bool __oneTimeSetupHasRun = false;
  27. private static object __oneTimeSetupLock = new object();
  28. public AggregationSample()
  29. {
  30. lock (__oneTimeSetupLock)
  31. {
  32. __oneTimeSetupHasRun = __oneTimeSetupHasRun || OneTimeSetup();
  33. }
  34. }
  35. public bool OneTimeSetup()
  36. {
  37. var client = DriverTestConfiguration.Client;
  38. var db = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
  39. db.DropCollection(DriverTestConfiguration.CollectionNamespace.CollectionName);
  40. __collection = db.GetCollection<ZipEntry>(DriverTestConfiguration.CollectionNamespace.CollectionName);
  41. // This is a subset of the data from the mongodb docs zip code aggregation examples
  42. __collection.InsertMany(new[]
  43. {
  44. new ZipEntry { Zip = "01053", City = "LEEDS", State = "MA", Population = 1350 },
  45. new ZipEntry { Zip = "01054", City = "LEVERETT", State = "MA", Population = 1748 },
  46. new ZipEntry { Zip = "01056", City = "LUDLOW", State = "MA", Population = 18820 },
  47. new ZipEntry { Zip = "01057", City = "MONSON", State = "MA", Population = 8194 },
  48. new ZipEntry { Zip = "36779", City = "SPROTT", State = "AL", Population = 1191 },
  49. new ZipEntry { Zip = "36782", City = "SWEET WATER", State = "AL", Population = 2444 },
  50. new ZipEntry { Zip = "36783", City = "THOMASTON", State = "AL", Population = 1527 },
  51. new ZipEntry { Zip = "36784", City = "THOMASVILLE", State = "AL", Population = 6229 },
  52. });
  53. return true;
  54. }
  55. [Fact]
  56. public async Task States_with_pops_over_20000()
  57. {
  58. var pipeline = __collection.Aggregate()
  59. .Group(x => x.State, g => new { State = g.Key, TotalPopulation = g.Sum(x => x.Population) })
  60. .Match(x => x.TotalPopulation > 20000);
  61. pipeline.ToString().Should().Be("aggregate([" +
  62. "{ \"$group\" : { \"_id\" : \"$state\", \"TotalPopulation\" : { \"$sum\" : \"$pop\" } } }, " +
  63. "{ \"$match\" : { \"TotalPopulation\" : { \"$gt\" : 20000 } } }])");
  64. var result = await pipeline.ToListAsync();
  65. result.Count.Should().Be(1);
  66. }
  67. [Fact]
  68. public async Task States_with_pops_over_20000_queryable_method()
  69. {
  70. var pipeline = __collection.AsQueryable()
  71. .GroupBy(x => x.State, (k, s) => new { State = k, TotalPopulation = s.Sum(x => x.Population) })
  72. .Where(x => x.TotalPopulation > 20000);
  73. var result = await pipeline.ToListAsync();
  74. result.Count.Should().Be(1);
  75. }
  76. #if !MONO
  77. [Fact]
  78. public async Task States_with_pops_over_20000_queryable_syntax()
  79. {
  80. var pipeline = from z in __collection.AsQueryable()
  81. group z by z.State into g
  82. where g.Sum(x => x.Population) > 20000
  83. select new { State = g.Key, TotalPopulation = g.Sum(x => x.Population) };
  84. var result = await pipeline.ToListAsync();
  85. result.Count.Should().Be(1);
  86. }
  87. #endif
  88. [Fact]
  89. public async Task Average_city_population_by_state()
  90. {
  91. var pipeline = __collection.Aggregate()
  92. .Group(x => new { State = x.State, City = x.City }, g => new { StateAndCity = g.Key, Population = g.Sum(x => x.Population) })
  93. .Group(x => x.StateAndCity.State, g => new { State = g.Key, AverageCityPopulation = g.Average(x => x.Population) })
  94. .SortBy(x => x.State);
  95. pipeline.ToString().Should().Be("aggregate([" +
  96. "{ \"$group\" : { \"_id\" : { \"State\" : \"$state\", \"City\" : \"$city\" }, \"Population\" : { \"$sum\" : \"$pop\" } } }, " +
  97. "{ \"$group\" : { \"_id\" : \"$_id.State\", \"AverageCityPopulation\" : { \"$avg\" : \"$Population\" } } }, " +
  98. "{ \"$sort\" : { \"_id\" : 1 } }])");
  99. var result = await pipeline.ToListAsync();
  100. result[0].State.Should().Be("AL");
  101. result[0].AverageCityPopulation.Should().Be(2847.75);
  102. result[1].AverageCityPopulation.Should().Be(7528);
  103. result[1].State.Should().Be("MA");
  104. }
  105. [Fact]
  106. public async Task Largest_and_smallest_cities_by_state()
  107. {
  108. var pipeline = __collection.Aggregate()
  109. .Group(x => new { State = x.State, City = x.City }, g => new { StateAndCity = g.Key, Population = g.Sum(x => x.Population) })
  110. .SortBy(x => x.Population)
  111. .Group(x => x.StateAndCity.State, g => new
  112. {
  113. State = g.Key,
  114. BiggestCity = g.Last().StateAndCity.City,
  115. BiggestPopulation = g.Last().Population,
  116. SmallestCity = g.First().StateAndCity.City,
  117. SmallestPopulation = g.First().Population
  118. })
  119. .Project(x => new
  120. {
  121. x.State,
  122. BiggestCity = new { Name = x.BiggestCity, Population = x.BiggestPopulation },
  123. SmallestCity = new { Name = x.SmallestCity, Population = x.SmallestPopulation }
  124. })
  125. .SortBy(x => x.State);
  126. pipeline.ToString().Should().Be("aggregate([" +
  127. "{ \"$group\" : { \"_id\" : { \"State\" : \"$state\", \"City\" : \"$city\" }, \"Population\" : { \"$sum\" : \"$pop\" } } }, " +
  128. "{ \"$sort\" : { \"Population\" : 1 } }, " +
  129. "{ \"$group\" : { \"_id\" : \"$_id.State\", \"BiggestCity\" : { \"$last\" : \"$_id.City\" }, \"BiggestPopulation\" : { \"$last\" : \"$Population\" }, \"SmallestCity\" : { \"$first\" : \"$_id.City\" }, \"SmallestPopulation\" : { \"$first\" : \"$Population\" } } }, " +
  130. "{ \"$project\" : { \"State\" : \"$_id\", \"BiggestCity\" : { \"Name\" : \"$BiggestCity\", \"Population\" : \"$BiggestPopulation\" }, \"SmallestCity\" : { \"Name\" : \"$SmallestCity\", \"Population\" : \"$SmallestPopulation\" }, \"_id\" : 0 } }, " +
  131. "{ \"$sort\" : { \"State\" : 1 } }])");
  132. var result = await pipeline.ToListAsync();
  133. result[0].State.Should().Be("AL");
  134. result[0].BiggestCity.Name.Should().Be("THOMASVILLE");
  135. result[0].BiggestCity.Population.Should().Be(6229);
  136. result[0].SmallestCity.Name.Should().Be("SPROTT");
  137. result[0].SmallestCity.Population.Should().Be(1191);
  138. result[1].State.Should().Be("MA");
  139. result[1].BiggestCity.Name.Should().Be("LUDLOW");
  140. result[1].BiggestCity.Population.Should().Be(18820);
  141. result[1].SmallestCity.Name.Should().Be("LEEDS");
  142. result[1].SmallestCity.Population.Should().Be(1350);
  143. }
  144. #if !MONO
  145. [Fact]
  146. public async Task Largest_and_smallest_cities_by_state_queryable_syntax()
  147. {
  148. var pipeline = from o in
  149. (
  150. from z in __collection.AsQueryable()
  151. group z by new { z.State, z.City } into g
  152. select new { StateAndCity = g.Key, Population = g.Sum(x => x.Population) }
  153. )
  154. orderby o.Population
  155. group o by o.StateAndCity.State into g
  156. orderby g.Key
  157. select new
  158. {
  159. State = g.Key,
  160. BiggestCity = new { Name = g.Last().StateAndCity.City, Population = g.Last().Population },
  161. SmallestCity = new { Name = g.First().StateAndCity.City, Population = g.First().Population }
  162. };
  163. var result = await pipeline.ToListAsync();
  164. result[0].State.Should().Be("AL");
  165. result[0].BiggestCity.Name.Should().Be("THOMASVILLE");
  166. result[0].BiggestCity.Population.Should().Be(6229);
  167. result[0].SmallestCity.Name.Should().Be("SPROTT");
  168. result[0].SmallestCity.Population.Should().Be(1191);
  169. result[1].State.Should().Be("MA");
  170. result[1].BiggestCity.Name.Should().Be("LUDLOW");
  171. result[1].BiggestCity.Population.Should().Be(18820);
  172. result[1].SmallestCity.Name.Should().Be("LEEDS");
  173. result[1].SmallestCity.Population.Should().Be(1350);
  174. }
  175. #endif
  176. [BsonIgnoreExtraElements]
  177. private class ZipEntry
  178. {
  179. [BsonId]
  180. public string Zip { get; set; }
  181. [BsonElement("city")]
  182. public string City { get; set; }
  183. [BsonElement("state")]
  184. public string State { get; set; }
  185. [BsonElement("pop")]
  186. public int Population { get; set; }
  187. }
  188. }
  189. }