PageRenderTime 36ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

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

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