/test/SlowTests/Tests/Faceted/Aggregation.cs

https://github.com/fitzchak/ravendb · C# · 572 lines · 482 code · 85 blank · 5 comment · 28 complexity · 2ededce9d4fbb696a4f27c6dca6b5d29 MD5 · raw file

  1. // -----------------------------------------------------------------------
  2. // <copyright file="Aggregation.cs" company="Hibernating Rhinos LTD">
  3. // Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using FastTests;
  10. using Raven.Client.Documents;
  11. using Raven.Client.Documents.Indexes;
  12. using Raven.Client.Documents.Linq;
  13. using SlowTests.Core.Utils.Entities.Faceted;
  14. using Sparrow;
  15. using Xunit;
  16. namespace SlowTests.Tests.Faceted
  17. {
  18. public class Aggregation : RavenTestBase
  19. {
  20. private class Orders_All : AbstractIndexCreationTask<Order>
  21. {
  22. public Orders_All()
  23. {
  24. Map = orders =>
  25. from order in orders
  26. select new
  27. {
  28. order.Currency,
  29. order.Product,
  30. order.Total,
  31. order.Quantity,
  32. order.Region,
  33. order.At,
  34. order.Tax
  35. };
  36. }
  37. }
  38. [Fact]
  39. public void CanCorrectlyAggregate_AnonymousTypes_Double()
  40. {
  41. using (var store = GetDocumentStore())
  42. {
  43. new Orders_All().Execute(store);
  44. using (var session = store.OpenSession())
  45. {
  46. var obj = new { Currency = Currency.EUR, Product = "Milk", Total = 1.1, Region = 1 };
  47. var obj2 = new { Currency = Currency.EUR, Product = "Milk", Total = 1, Region = 1 };
  48. session.Store(obj);
  49. session.Store(obj2);
  50. session.Advanced.GetMetadataFor(obj)["@collection"] = "Orders";
  51. session.Advanced.GetMetadataFor(obj2)["@collection"] = "Orders";
  52. session.SaveChanges();
  53. }
  54. WaitForIndexing(store);
  55. using (var session = store.OpenSession())
  56. {
  57. var r = session.Query<Order>("Orders/All")
  58. .AggregateBy(factory => factory.ByField(x => x.Region).MaxOn(x => x.Total).MinOn(x => x.Total))
  59. .Execute();
  60. var facetResult = r["Region"];
  61. Assert.Equal(2, facetResult.Values[0].Count);
  62. Assert.Equal(1, facetResult.Values[0].Min);
  63. Assert.Equal(1.1, facetResult.Values[0].Max);
  64. Assert.Equal(1, facetResult.Values.Count(x => x.Range == "1"));
  65. }
  66. }
  67. }
  68. [Fact]
  69. public void CanCorrectlyAggregate_AnonymousTypes_Float()
  70. {
  71. using (var store = GetDocumentStore())
  72. {
  73. new Orders_All().Execute(store);
  74. using (var session = store.OpenSession())
  75. {
  76. var obj = new { Currency = Currency.EUR, Product = "Milk", Total = 1.1, Region = 1, Tax = 1 };
  77. var obj2 = new { Currency = Currency.EUR, Product = "Milk", Total = 1, Region = 1, Tax = 1.5 };
  78. session.Store(obj);
  79. session.Store(obj2);
  80. session.Advanced.GetMetadataFor(obj)["@collection"] = "Orders";
  81. session.Advanced.GetMetadataFor(obj2)["@collection"] = "Orders";
  82. session.SaveChanges();
  83. }
  84. WaitForIndexing(store);
  85. using (var session = store.OpenSession())
  86. {
  87. var r = session.Query<Order>("Orders/All")
  88. .AggregateBy(factory => factory.ByField(x => x.Region).MaxOn(x => x.Tax).MinOn(x => x.Tax))
  89. .Execute();
  90. var facetResult = r["Region"];
  91. Assert.Equal(2, facetResult.Values[0].Count);
  92. Assert.Equal(1, facetResult.Values[0].Min);
  93. Assert.Equal(1.5, facetResult.Values[0].Max);
  94. Assert.Equal(1, facetResult.Values.Count(x => x.Range == "1"));
  95. }
  96. }
  97. }
  98. [Fact]
  99. public void CanCorrectlyAggregate_AnonymousTypes_Int()
  100. {
  101. using (var store = GetDocumentStore())
  102. {
  103. new Orders_All().Execute(store);
  104. using (var session = store.OpenSession())
  105. {
  106. var obj = new { Currency = Currency.EUR, Product = "Milk", Quantity = 1.0, Total = 1.1, Region = 1, Tax = 1 };
  107. var obj2 = new { Currency = Currency.EUR, Product = "Milk", Quantity = 2, Total = 1, Region = 1, Tax = 1.5 };
  108. session.Store(obj);
  109. session.Store(obj2);
  110. session.Advanced.GetMetadataFor(obj)["@collection"] = "Orders";
  111. session.Advanced.GetMetadataFor(obj2)["@collection"] = "Orders";
  112. session.SaveChanges();
  113. }
  114. WaitForIndexing(store);
  115. using (var session = store.OpenSession())
  116. {
  117. var r = session.Query<Order>("Orders/All")
  118. .AggregateBy(factory => factory.ByField(x => x.Region).MaxOn(x => x.Quantity).MinOn(x => x.Quantity))
  119. .Execute();
  120. var facetResult = r["Region"];
  121. Assert.Equal(2, facetResult.Values[0].Count);
  122. Assert.Equal(1, facetResult.Values[0].Min);
  123. Assert.Equal(2, facetResult.Values[0].Max);
  124. Assert.Equal(1, facetResult.Values.Count(x => x.Range == "1"));
  125. }
  126. }
  127. }
  128. [Fact]
  129. public void CanCorrectlyAggregate_AnonymousTypes_Long()
  130. {
  131. using (var store = GetDocumentStore())
  132. {
  133. new Orders_All().Execute(store);
  134. using (var session = store.OpenSession())
  135. {
  136. var obj = new { Currency = Currency.EUR, Product = "Milk", Total = 1.1, Region = 1.0, Tax = 1 };
  137. var obj2 = new { Currency = Currency.EUR, Product = "Milk", Total = 1, Region = 2, Tax = 1.5 };
  138. session.Store(obj);
  139. session.Store(obj2);
  140. session.Advanced.GetMetadataFor(obj)["@collection"] = "Orders";
  141. session.Advanced.GetMetadataFor(obj2)["@collection"] = "Orders";
  142. session.SaveChanges();
  143. }
  144. WaitForIndexing(store);
  145. using (var session = store.OpenSession())
  146. {
  147. var r = session.Query<Order>("Orders/All")
  148. .AggregateBy(factory => factory.ByField(x => x.Product).MaxOn(x => x.Region).MinOn(x => x.Region))
  149. .Execute();
  150. var facetResult = r["Product"];
  151. Assert.Equal(2, facetResult.Values[0].Count);
  152. Assert.Equal(1, facetResult.Values[0].Min);
  153. Assert.Equal(2, facetResult.Values[0].Max);
  154. Assert.Equal(1, facetResult.Values.Count(x => x.Range == "milk"));
  155. }
  156. }
  157. }
  158. [Fact]
  159. public void CanCorrectlyAggregate()
  160. {
  161. using (var store = GetDocumentStore())
  162. {
  163. new Orders_All().Execute(store);
  164. using (var session = store.OpenSession())
  165. {
  166. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3 });
  167. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9 });
  168. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333 });
  169. session.SaveChanges();
  170. }
  171. WaitForIndexing(store);
  172. using (var session = store.OpenSession())
  173. {
  174. var r = session.Query<Order, Orders_All>()
  175. .AggregateBy(f => f.ByField(x => x.Product).SumOn(x => x.Total))
  176. .Execute();
  177. var facetResult = r["Product"];
  178. Assert.Equal(2, facetResult.Values.Count);
  179. Assert.Equal(12, facetResult.Values.First(x => x.Range == "milk").Sum);
  180. Assert.Equal(3333, facetResult.Values.First(x => x.Range == "iphone").Sum);
  181. }
  182. }
  183. }
  184. [Fact]
  185. public void CanCorrectlyAggregate_MultipleItems()
  186. {
  187. using (var store = GetDocumentStore())
  188. {
  189. new Orders_All().Execute(store);
  190. using (var session = store.OpenSession())
  191. {
  192. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3 });
  193. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9 });
  194. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333 });
  195. session.SaveChanges();
  196. }
  197. WaitForIndexing(store);
  198. using (var session = store.OpenSession())
  199. {
  200. var r = session.Query<Order>("Orders/All")
  201. .AggregateBy(x => x.ByField(y => y.Product).SumOn(y => y.Total))
  202. .AndAggregateBy(x => x.ByField(order => order.Currency).SumOn(y => y.Total))
  203. .Execute();
  204. var facetResult = r["Product"];
  205. Assert.Equal(2, facetResult.Values.Count);
  206. Assert.Equal(12, facetResult.Values.First(x => x.Range == "milk").Sum);
  207. Assert.Equal(3333, facetResult.Values.First(x => x.Range == "iphone").Sum);
  208. facetResult = r["Currency"];
  209. Assert.Equal(2, facetResult.Values.Count);
  210. Assert.Equal(3336, facetResult.Values.First(x => x.Range == "eur").Sum);
  211. Assert.Equal(9, facetResult.Values.First(x => x.Range == "nis").Sum);
  212. }
  213. }
  214. }
  215. [Fact]
  216. public void CanCorrectlyAggregate_MultipleAggregations()
  217. {
  218. using (var store = GetDocumentStore())
  219. {
  220. new Orders_All().Execute(store);
  221. using (var session = store.OpenSession())
  222. {
  223. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3 });
  224. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9 });
  225. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333 });
  226. session.SaveChanges();
  227. }
  228. WaitForIndexing(store);
  229. using (var session = store.OpenSession())
  230. {
  231. var r = session.Query<Order>("Orders/All")
  232. .AggregateBy(factory => factory.ByField(x => x.Product).MaxOn(x => x.Total).MinOn(x => x.Total))
  233. .Execute();
  234. var facetResult = r["Product"];
  235. Assert.Equal(2, facetResult.Values.Count);
  236. Assert.Equal(9, facetResult.Values.First(x => x.Range == "milk").Max);
  237. Assert.Equal(3, facetResult.Values.First(x => x.Range == "milk").Min);
  238. Assert.Equal(3333, facetResult.Values.First(x => x.Range == "iphone").Max);
  239. Assert.Equal(3333, facetResult.Values.First(x => x.Range == "iphone").Min);
  240. }
  241. }
  242. }
  243. [Fact]
  244. public void CanCorrectlyAggregate_LongDataType()
  245. {
  246. using (var store = GetDocumentStore())
  247. {
  248. new Orders_All().Execute(store);
  249. using (var session = store.OpenSession())
  250. {
  251. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3, Region = 1 });
  252. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9, Region = 1 });
  253. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333, Region = 2 });
  254. session.SaveChanges();
  255. }
  256. WaitForIndexing(store);
  257. using (var session = store.OpenSession())
  258. {
  259. var r = session.Query<Order>("Orders/All")
  260. .AggregateBy(factory => factory.ByField(x => x.Region).MaxOn(x => x.Total).MinOn(x => x.Total))
  261. .Execute();
  262. var facetResult = r["Region"];
  263. Assert.Equal(2, facetResult.Values.Count);
  264. Assert.Equal(1, facetResult.Values.Count(x => x.Range == "1"));
  265. }
  266. }
  267. }
  268. [Fact]
  269. public void CanCorrectlyAggregate_DateTimeDataType()
  270. {
  271. using (var store = GetDocumentStore())
  272. {
  273. new Orders_All().Execute(store);
  274. using (var session = store.OpenSession())
  275. {
  276. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3, Region = 1, At = DateTime.Today });
  277. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9, Region = 1, At = DateTime.Today.AddDays(-1) });
  278. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333, Region = 2, At = DateTime.Today });
  279. session.SaveChanges();
  280. }
  281. WaitForIndexing(store);
  282. using (var session = store.OpenSession())
  283. {
  284. var r = session.Query<Order>("Orders/All")
  285. .AggregateBy(factory => factory.ByField(x => x.At).MaxOn(x => x.Total).MinOn(x => x.Total))
  286. .Execute();
  287. var facetResult = r["At"];
  288. Assert.Equal(2, facetResult.Values.Count);
  289. Assert.Equal(1, facetResult.Values.Count(x => x.Range == DateTime.Today.ToString(DefaultFormat.DateTimeFormatsToWrite)));
  290. }
  291. }
  292. }
  293. [Fact]
  294. public void CanCorrectlyAggregate_DisplayName()
  295. {
  296. using (var store = GetDocumentStore())
  297. {
  298. new Orders_All().Execute(store);
  299. using (var session = store.OpenSession())
  300. {
  301. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3 });
  302. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9 });
  303. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333 });
  304. session.SaveChanges();
  305. }
  306. WaitForIndexing(store);
  307. using (var session = store.OpenSession())
  308. {
  309. var r = session.Query<Order>("Orders/All")
  310. .AggregateBy(f => f.ByField(x => x.Product).WithDisplayName("ProductMax").MaxOn(x => x.Total))
  311. .AndAggregateBy(f => f.ByField(x => x.Product).WithDisplayName("ProductMin"))
  312. .Execute();
  313. Assert.Equal(2, r.Count);
  314. Assert.NotNull(r["ProductMax"]);
  315. Assert.NotNull(r["ProductMin"]);
  316. Assert.Equal(3333, r["ProductMax"].Values.First().Max);
  317. Assert.Equal(2, r["ProductMin"].Values[1].Count);
  318. }
  319. }
  320. }
  321. [Fact]
  322. public void CanCorrectlyAggregate_Ranges()
  323. {
  324. using (var store = GetDocumentStore())
  325. {
  326. new Orders_All().Execute(store);
  327. using (var session = store.OpenSession())
  328. {
  329. session.Store(new Order { Currency = Currency.EUR, Product = "Milk", Total = 3 });
  330. session.Store(new Order { Currency = Currency.NIS, Product = "Milk", Total = 9 });
  331. session.Store(new Order { Currency = Currency.EUR, Product = "iPhone", Total = 3333 });
  332. session.SaveChanges();
  333. }
  334. WaitForIndexing(store);
  335. using (var session = store.OpenSession())
  336. {
  337. var r = session.Query<Order>("Orders/All")
  338. .AggregateBy(f => f.ByField(x => x.Product).SumOn(x => x.Total))
  339. .AndAggregateBy(f => f
  340. .ByRanges(
  341. x => x.Total < 100,
  342. x => x.Total >= 100 && x.Total < 500,
  343. x => x.Total >= 500 && x.Total < 1500,
  344. x => x.Total >= 1500)
  345. .SumOn(x => x.Total))
  346. .Execute();
  347. var facetResult = r["Product"];
  348. Assert.Equal(2, facetResult.Values.Count);
  349. Assert.Equal(12, facetResult.Values.First(x => x.Range == "milk").Sum);
  350. Assert.Equal(3333, facetResult.Values.First(x => x.Range == "iphone").Sum);
  351. facetResult = r["Total"];
  352. Assert.Equal(4, facetResult.Values.Count);
  353. Assert.Equal(12, facetResult.Values.First(x => x.Range == "Total < 100.0").Sum);
  354. Assert.Equal(3333, facetResult.Values.First(x => x.Range == "Total >= 1500.0").Sum);
  355. }
  356. }
  357. }
  358. [Fact]
  359. public void CanCorrectlyAggregate_DateTimeDataType_WithRangeCounts()
  360. {
  361. using (var store = GetDocumentStore())
  362. {
  363. new ItemsOrders_All().Execute(store);
  364. using (var session = store.OpenSession())
  365. {
  366. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today });
  367. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today.AddDays(-1) });
  368. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today });
  369. session.Store(new ItemsOrder { Items = new List<string> { "first" }, At = DateTime.Today });
  370. session.SaveChanges();
  371. }
  372. var minValue = DateTime.MinValue;
  373. var end0 = DateTime.Today.AddDays(-2);
  374. var end1 = DateTime.Today.AddDays(-1);
  375. var end2 = DateTime.Today;
  376. WaitForIndexing(store);
  377. using (var session = store.OpenSession())
  378. {
  379. var r = session.Query<ItemsOrder>("ItemsOrders/All")
  380. .Where(x => x.At >= end0)
  381. .AggregateBy(f => f.ByRanges(
  382. x => x.At >= minValue, // all - 4
  383. x => x.At >= end0 && x.At < end1, // 0
  384. x => x.At >= end1 && x.At < end2 // 1
  385. ))
  386. .Execute();
  387. var facetResults = r["At"].Values;
  388. Assert.Equal(4, facetResults[0].Count);
  389. Assert.Equal(0, facetResults[1].Count);
  390. Assert.Equal(1, facetResults[2].Count);
  391. }
  392. }
  393. }
  394. [Fact]
  395. public void CanCorrectlyAggregate_DateTimeDataType_WithRangeCounts_AndInOperator_AfterOtherWhere()
  396. {
  397. using (var store = GetDocumentStore())
  398. {
  399. new ItemsOrders_All().Execute(store);
  400. using (var session = store.OpenSession())
  401. {
  402. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today });
  403. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today.AddDays(-1) });
  404. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today });
  405. session.Store(new ItemsOrder { Items = new List<string> { "first" }, At = DateTime.Today });
  406. session.SaveChanges();
  407. }
  408. var items = new List<string> { "second" };
  409. var minValue = DateTime.MinValue;
  410. var end0 = DateTime.Today.AddDays(-2);
  411. var end1 = DateTime.Today.AddDays(-1);
  412. var end2 = DateTime.Today;
  413. WaitForIndexing(store);
  414. using (var session = store.OpenSession())
  415. {
  416. var r = session.Query<ItemsOrder>("ItemsOrders/All")
  417. .Where(x => x.At >= end0)
  418. .Where(x => x.Items.In(items))
  419. .AggregateBy(f => f.ByRanges(
  420. x => x.At >= minValue, // all - 3
  421. x => x.At >= end0 && x.At < end1, // 0
  422. x => x.At >= end1 && x.At < end2 // 1
  423. ))
  424. .Execute();
  425. var facetResults = r["At"].Values;
  426. Assert.Equal(3, facetResults[0].Count);
  427. Assert.Equal(0, facetResults[1].Count);
  428. Assert.Equal(1, facetResults[2].Count);
  429. }
  430. }
  431. }
  432. [Fact]
  433. public void CanCorrectlyAggregate_DateTimeDataType_WithRangeCounts_AndInOperator_BeforeOtherWhere()
  434. {
  435. using (var store = GetDocumentStore())
  436. {
  437. new ItemsOrders_All().Execute(store);
  438. using (var session = store.OpenSession())
  439. {
  440. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today });
  441. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today.AddDays(-1) });
  442. session.Store(new ItemsOrder { Items = new List<string> { "first", "second" }, At = DateTime.Today });
  443. session.Store(new ItemsOrder { Items = new List<string> { "first" }, At = DateTime.Today });
  444. session.SaveChanges();
  445. }
  446. var items = new List<string> { "second" };
  447. var minValue = DateTime.MinValue;
  448. var end0 = DateTime.Today.AddDays(-2);
  449. var end1 = DateTime.Today.AddDays(-1);
  450. var end2 = DateTime.Today;
  451. WaitForIndexing(store);
  452. using (var session = store.OpenSession())
  453. {
  454. var r = session.Query<ItemsOrder>("ItemsOrders/All")
  455. .Where(x => x.Items.In(items))
  456. .Where(x => x.At >= end0)
  457. .AggregateBy(
  458. f => f
  459. .ByRanges(
  460. x => x.At >= minValue, // all - 3
  461. x => x.At >= end0 && x.At < end1, // 0
  462. x => x.At >= end1 && x.At < end2 // 1
  463. ))
  464. .Execute();
  465. var facetResults = r["At"].Values;
  466. Assert.Equal(3, facetResults[0].Count);
  467. Assert.Equal(0, facetResults[1].Count);
  468. Assert.Equal(1, facetResults[2].Count);
  469. }
  470. }
  471. }
  472. private class ItemsOrder
  473. {
  474. public List<string> Items { get; set; }
  475. public DateTime At { get; set; }
  476. }
  477. private class ItemsOrders_All : AbstractIndexCreationTask<ItemsOrder>
  478. {
  479. public ItemsOrders_All()
  480. {
  481. Map = orders =>
  482. from order in orders
  483. select new { order.At, order.Items };
  484. }
  485. }
  486. }
  487. }