PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Tests/Spatial/SpatialIndex.cs

http://github.com/ravendb/ravendb
C# | 236 lines | 196 code | 34 blank | 6 comment | 11 complexity | 168eb055c4c9b86f3c7155b383692471 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  1. //-----------------------------------------------------------------------
  2. // <copyright file="SpatialIndex.cs" company="Hibernating Rhinos LTD">
  3. // Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4. // </copyright>
  5. //-----------------------------------------------------------------------
  6. using System;
  7. using System.Diagnostics;
  8. using System.IO;
  9. using System.Collections.Generic;
  10. using System.ComponentModel;
  11. using System.ComponentModel.Composition.Hosting;
  12. using System.Linq;
  13. using System.Threading;
  14. using Newtonsoft.Json;
  15. using Raven.Abstractions.Data;
  16. using Raven.Abstractions.Extensions;
  17. using Raven.Abstractions.Indexing;
  18. using Raven.Json.Linq;
  19. using Raven.Database;
  20. using Raven.Database.Config;
  21. using Raven.Database.Data;
  22. using Raven.Database.Indexing;
  23. using Raven.Database.Linq;
  24. using Raven.Tests.Storage;
  25. using Xunit;
  26. using Raven.Database.Json;
  27. namespace Raven.Tests.Spatial
  28. {
  29. public class SpatialIndex : AbstractDocumentStorageTest
  30. {
  31. private readonly DocumentDatabase db;
  32. public SpatialIndex()
  33. {
  34. db = new DocumentDatabase(new RavenConfiguration
  35. {
  36. DataDirectory = "raven.db.test.esent",
  37. RunInUnreliableYetFastModeThatIsNotSuitableForProduction = true
  38. });
  39. db.SpinBackgroundWorkers();
  40. }
  41. #region IDisposable Members
  42. public override void Dispose()
  43. {
  44. db.Dispose();
  45. base.Dispose();
  46. }
  47. #endregion
  48. // same test as in Spatial.Net test cartisian
  49. [Fact]
  50. public void CanPerformSpatialSearch()
  51. {
  52. var indexDefinition = new IndexDefinition
  53. {
  54. Map = "from e in docs.Events select new { Tag = \"Event\", _ = SpatialIndex.Generate(e.Latitude, e.Longitude) }",
  55. Indexes = {
  56. { "Tag", FieldIndexing.NotAnalyzed }
  57. }
  58. };
  59. db.PutIndex("eventsByLatLng", indexDefinition);
  60. var events = SpatialIndexTestHelper.GetEvents();
  61. for (int i = 0; i < events.Length; i++)
  62. {
  63. db.Put("Events/" + (i + 1), null,
  64. RavenJObject.FromObject(events[i]),
  65. RavenJObject.Parse("{'Raven-Entity-Name': 'Events'}"), null);
  66. }
  67. const double lat = 38.96939, lng = -77.386398;
  68. const double radius = 6.0;
  69. QueryResult queryResult;
  70. do
  71. {
  72. queryResult = db.Query("eventsByLatLng", new SpatialIndexQuery()
  73. {
  74. Query = "Tag:[[Event]]",
  75. Latitude = lat,
  76. Longitude = lng,
  77. Radius = radius,
  78. SortedFields = new[]{new SortedField("__distance"), }
  79. });
  80. if (queryResult.IsStale)
  81. Thread.Sleep(100);
  82. } while (queryResult.IsStale);
  83. Assert.Equal(7, queryResult.Results.Count);
  84. double previous = 0;
  85. foreach (var r in queryResult.Results)
  86. {
  87. Event e = r.JsonDeserialization<Event>();
  88. double distance = Raven.Database.Indexing.SpatialIndex.GetDistanceMi(lat, lng, e.Latitude, e.Longitude);
  89. Console.WriteLine("Venue: " + e.Venue + ", Distance " + distance);
  90. Assert.True(distance < radius);
  91. Assert.True(distance >= previous);
  92. previous = distance;
  93. }
  94. }
  95. [Fact]
  96. public void CanSortByDistanceAndAnotherProp()
  97. {
  98. var indexDefinition = new IndexDefinition
  99. {
  100. Map = "from e in docs.Events select new { e.Venue, _ = SpatialIndex.Generate(e.Latitude, e.Longitude) }",
  101. Indexes = {
  102. { "Tag", FieldIndexing.NotAnalyzed }
  103. }
  104. };
  105. db.PutIndex("eventsByLatLng", indexDefinition);
  106. var events = new[]
  107. {
  108. new Event("a/1", 38.9579000, -77.3572000),
  109. new Event("b/1", 38.9579000, -77.3572000),
  110. new Event("c/1", 38.9579000, -77.3572000),
  111. new Event("a/2", 38.9690000, -77.3862000),
  112. new Event("b/2", 38.9690000, -77.3862000),
  113. new Event("c/2", 38.9690000, -77.3862000),
  114. new Event("a/3", 38.9510000, -77.4107000),
  115. new Event("b/3", 38.9510000, -77.4107000),
  116. new Event("c/3", 38.9510000, -77.4107000),
  117. };
  118. for (int i = 0; i < events.Length; i++)
  119. {
  120. db.Put("Events/" + (i + 1), null,
  121. RavenJObject.FromObject(events[i]),
  122. RavenJObject.Parse("{'Raven-Entity-Name': 'Events'}"), null);
  123. }
  124. const double lat = 38.96939, lng = -77.386398;
  125. const double radius = 6.0;
  126. QueryResult queryResult;
  127. do
  128. {
  129. queryResult = db.Query("eventsByLatLng", new SpatialIndexQuery()
  130. {
  131. Latitude = lat,
  132. Longitude = lng,
  133. Radius = radius,
  134. SortedFields = new[]
  135. {
  136. new SortedField("__distance"),
  137. new SortedField("Venue"),
  138. }
  139. });
  140. if (queryResult.IsStale)
  141. Thread.Sleep(100);
  142. } while (queryResult.IsStale);
  143. Assert.Equal(9, queryResult.Results.Count);
  144. var expectedOrder = new[] {"a/2", "b/2", "c/2", "a/1", "b/1", "c/1", "a/3", "b/3", "c/3"};
  145. for (int i = 0; i < queryResult.Results.Count; i++)
  146. {
  147. Assert.Equal(expectedOrder[i], queryResult.Results[i].Value<string>("Venue"));
  148. }
  149. }
  150. [Fact]
  151. public void CanSortByAnotherPropAnddistance()
  152. {
  153. var indexDefinition = new IndexDefinition
  154. {
  155. Map = "from e in docs.Events select new { e.Venue, _ = SpatialIndex.Generate(e.Latitude, e.Longitude) }",
  156. Indexes = {
  157. { "Tag", FieldIndexing.NotAnalyzed }
  158. }
  159. };
  160. db.PutIndex("eventsByLatLng", indexDefinition);
  161. var events = new[]
  162. {
  163. new Event("b", 38.9579000, -77.3572000),
  164. new Event("b", 38.9690000, -77.3862000),
  165. new Event("b", 38.9510000, -77.4107000),
  166. new Event("a", 38.9579000, -77.3572000),
  167. new Event("a", 38.9690000, -77.3862000),
  168. new Event("a", 38.9510000, -77.4107000),
  169. };
  170. for (int i = 0; i < events.Length; i++)
  171. {
  172. db.Put("Events/" + (i + 1), null,
  173. RavenJObject.FromObject(events[i]),
  174. RavenJObject.Parse("{'Raven-Entity-Name': 'Events'}"), null);
  175. }
  176. const double lat = 38.96939, lng = -77.386398;
  177. const double radius = 6.0;
  178. QueryResult queryResult;
  179. do
  180. {
  181. queryResult = db.Query("eventsByLatLng", new SpatialIndexQuery()
  182. {
  183. Latitude = lat,
  184. Longitude = lng,
  185. Radius = radius,
  186. SortedFields = new[]
  187. {
  188. new SortedField("Venue"),
  189. new SortedField("__distance"),
  190. }
  191. });
  192. if (queryResult.IsStale)
  193. Thread.Sleep(100);
  194. } while (queryResult.IsStale);
  195. var expectedOrder = new[] { "events/5", "events/4", "events/6", "events/2", "events/1", "events/3", };
  196. for (int i = 0; i < queryResult.Results.Count; i++)
  197. {
  198. Assert.Equal(expectedOrder[i], queryResult.Results[i].Value<RavenJObject>("@metadata").Value<string>("@id"));
  199. }
  200. }
  201. }
  202. }