github.com/altipla-consulting/ravendb-go-client@v0.1.3/tests/spatial_sorting_test.go (about) 1 package tests 2 3 import ( 4 "fmt" 5 "testing" 6 7 ravendb "github.com/altipla-consulting/ravendb-go-client" 8 "github.com/stretchr/testify/assert" 9 ) 10 11 const ( 12 FilteredLat = float64(44.419575) 13 FilteredLng = float64(34.042618) 14 SortedLat = float64(44.417398) 15 SortedLng = float64(34.042575) 16 FilteredRadius = float64(100) 17 ) 18 19 type Shop struct { 20 ID string 21 Latitude float64 `json:"latitude"` 22 Longitude float64 `json:"longitude"` 23 } 24 25 func NewShop(latitude float64, longitude float64) *Shop { 26 return &Shop{ 27 Latitude: latitude, 28 Longitude: longitude, 29 } 30 } 31 32 var ( 33 shops = []*Shop{ 34 NewShop(44.420678, 34.042490), 35 NewShop(44.419712, 34.042232), 36 NewShop(44.418686, 34.043219), 37 } 38 //shop/1:0.36KM, shop/2:0.26KM, shop/3 0.15KM from (34.042575, 44.417398) 39 sortedExpectedOrder = []string{"shops/3-A", "shops/2-A", "shops/1-A"} 40 41 //shop/1:0.12KM, shop/2:0.03KM, shop/3 0.11KM from (34.042618, 44.419575) 42 filteredExpectedOrder = []string{"shops/2-A", "shops/3-A", "shops/1-A"} 43 ) 44 45 func spatialSortingCreateData(t *testing.T, driver *RavenTestDriver, store *ravendb.DocumentStore) { 46 var err error 47 indexDefinition := ravendb.NewIndexDefinition() 48 indexDefinition.Name = "eventsByLatLng" 49 indexDefinition.Maps = []string{"from e in docs.Shops select new { e.venue, coordinates = CreateSpatialField(e.latitude, e.longitude) }"} 50 51 fields := make(map[string]*ravendb.IndexFieldOptions) 52 options := ravendb.NewIndexFieldOptions() 53 options.Indexing = ravendb.FieldIndexingExact 54 fields["tag"] = options 55 indexDefinition.Fields = fields 56 57 op := ravendb.NewPutIndexesOperation(indexDefinition) 58 err = store.Maintenance().Send(op) 59 assert.NoError(t, err) 60 61 indexDefinition2 := ravendb.NewIndexDefinition() 62 indexDefinition2.Name = "eventsByLatLngWSpecialField" 63 indexDefinition2.Maps = []string{"from e in docs.Shops select new { e.venue, mySpacialField = CreateSpatialField(e.latitude, e.longitude) }"} 64 65 indexFieldOptions := ravendb.NewIndexFieldOptions() 66 indexFieldOptions.Indexing = ravendb.FieldIndexingExact 67 fields = map[string]*ravendb.IndexFieldOptions{ 68 "tag": indexFieldOptions, 69 } 70 indexDefinition2.Fields = fields 71 72 op = ravendb.NewPutIndexesOperation(indexDefinition2) 73 err = store.Maintenance().Send(op) 74 assert.NoError(t, err) 75 76 { 77 session := openSessionMust(t, store) 78 for _, shop := range shops { 79 err = session.Store(shop) 80 assert.NoError(t, err) 81 } 82 83 err = session.SaveChanges() 84 assert.NoError(t, err) 85 86 session.Close() 87 } 88 89 err = driver.waitForIndexing(store, "", 0) 90 assert.NoError(t, err) 91 } 92 93 func assertResultsOrder(t *testing.T, resultIDs []string, expectedOrder []string) { 94 ok := stringArrayContainsExactly(resultIDs, expectedOrder) 95 assert.True(t, ok) 96 } 97 98 func spatialSortingCanFilterByLocationAndSortByDistanceFromDifferentPointWDocQuery(t *testing.T, 99 driver *RavenTestDriver) { 100 store := driver.getDocumentStoreMust(t) 101 defer store.Close() 102 103 spatialSortingCreateData(t, driver, store) 104 105 { 106 session := openSessionMust(t, store) 107 108 var shops []*Shop 109 q := session.QueryIndex("eventsByLatLng") 110 fn := func(f *ravendb.SpatialCriteriaFactory) ravendb.SpatialCriteria { 111 res := f.Within(getQueryShapeFromLatLon(FilteredLat, FilteredLng, FilteredRadius)) 112 return res 113 } 114 115 q = q.Spatial3("coordinates", fn) 116 q = q.OrderByDistanceLatLong("coordinates", SortedLat, SortedLng) 117 err := q.GetResults(&shops) 118 assert.NoError(t, err) 119 assert.Equal(t, len(shops), len(sortedExpectedOrder)) 120 121 ids := getShopIDs(shops) 122 assertResultsOrder(t, ids, sortedExpectedOrder) 123 124 session.Close() 125 } 126 } 127 128 func getShopIDs(shops []*Shop) []string { 129 var res []string 130 for _, shop := range shops { 131 id := shop.ID 132 res = append(res, id) 133 } 134 return res 135 } 136 137 func spatialSortingCanSortByDistanceWOFilteringWDocQuery(t *testing.T, driver *RavenTestDriver) { 138 store := driver.getDocumentStoreMust(t) 139 defer store.Close() 140 141 spatialSortingCreateData(t, driver, store) 142 143 { 144 session := openSessionMust(t, store) 145 146 var shops []*Shop 147 q := session.QueryIndex("eventsByLatLng") 148 q = q.OrderByDistanceLatLong("coordinates", SortedLat, SortedLng) 149 150 err := q.GetResults(&shops) 151 assert.NoError(t, err) 152 assert.Equal(t, len(shops), len(sortedExpectedOrder)) 153 154 ids := getShopIDs(shops) 155 assertResultsOrder(t, ids, sortedExpectedOrder) 156 157 session.Close() 158 } 159 } 160 161 func spatialSortingCanSortByDistanceWOFilteringWDocQueryBySpecifiedField(t *testing.T, driver *RavenTestDriver) { 162 store := driver.getDocumentStoreMust(t) 163 defer store.Close() 164 165 spatialSortingCreateData(t, driver, store) 166 167 { 168 session := openSessionMust(t, store) 169 170 var shops []*Shop 171 q := session.QueryIndex("eventsByLatLngWSpecialField") 172 q = q.OrderByDistanceLatLong("mySpacialField", SortedLat, SortedLng) 173 err := q.GetResults(&shops) 174 assert.NoError(t, err) 175 assert.Equal(t, len(shops), len(sortedExpectedOrder)) 176 177 ids := getShopIDs(shops) 178 assertResultsOrder(t, ids, sortedExpectedOrder) 179 180 session.Close() 181 } 182 } 183 184 func spatialSortingCanSortByDistanceWOFiltering(t *testing.T, driver *RavenTestDriver) { 185 store := driver.getDocumentStoreMust(t) 186 defer store.Close() 187 188 spatialSortingCreateData(t, driver, store) 189 190 { 191 session := openSessionMust(t, store) 192 193 var shops []*Shop 194 q := session.QueryIndex("eventsByLatLng") 195 q = q.OrderByDistanceLatLong("coordinates", FilteredLat, FilteredLng) 196 err := q.GetResults(&shops) 197 198 assert.NoError(t, err) 199 assert.Equal(t, len(shops), len(filteredExpectedOrder)) 200 201 ids := getShopIDs(shops) 202 assertResultsOrder(t, ids, filteredExpectedOrder) 203 204 session.Close() 205 } 206 207 { 208 session := openSessionMust(t, store) 209 210 var shops []*Shop 211 q := session.QueryIndex("eventsByLatLng") 212 q = q.OrderByDistanceDescendingLatLong("coordinates", FilteredLat, FilteredLng) 213 err := q.GetResults(&shops) 214 215 assert.NoError(t, err) 216 assert.Equal(t, len(shops), len(filteredExpectedOrder)) 217 218 ids := getShopIDs(shops) 219 stringArrayReverse(ids) 220 assertResultsOrder(t, ids, filteredExpectedOrder) 221 222 session.Close() 223 } 224 } 225 226 func spatialSortingCanSortByDistanceWOFilteringBySpecifiedField(t *testing.T, driver *RavenTestDriver) { 227 store := driver.getDocumentStoreMust(t) 228 defer store.Close() 229 230 spatialSortingCreateData(t, driver, store) 231 232 { 233 session := openSessionMust(t, store) 234 235 var shops []*Shop 236 q := session.QueryIndex("eventsByLatLngWSpecialField") 237 q = q.OrderByDistanceLatLong("mySpacialField", FilteredLat, FilteredLng) 238 err := q.GetResults(&shops) 239 240 assert.NoError(t, err) 241 assert.Equal(t, len(shops), len(filteredExpectedOrder)) 242 243 ids := getShopIDs(shops) 244 assertResultsOrder(t, ids, filteredExpectedOrder) 245 246 session.Close() 247 } 248 249 { 250 session := openSessionMust(t, store) 251 252 var shops []*Shop 253 q := session.QueryIndex("eventsByLatLngWSpecialField") 254 q = q.OrderByDistanceDescendingLatLong("mySpacialField", FilteredLat, FilteredLng) 255 err := q.GetResults(&shops) 256 257 assert.NoError(t, err) 258 assert.Equal(t, len(shops), len(filteredExpectedOrder)) 259 260 ids := getShopIDs(shops) 261 stringArrayReverse(ids) 262 assertResultsOrder(t, ids, filteredExpectedOrder) 263 264 session.Close() 265 } 266 } 267 268 func getQueryShapeFromLatLon(lat float64, lng float64, radius float64) string { 269 return fmt.Sprintf("Circle(%f %f d=%f)", lng, lat, radius) 270 } 271 272 func TestSpatialSorting(t *testing.T) { 273 driver := createTestDriver(t) 274 destroy := func() { destroyDriver(t, driver) } 275 defer recoverTest(t, destroy) 276 277 // matches order of Java tests 278 spatialSortingCanSortByDistanceWOFilteringBySpecifiedField(t, driver) 279 spatialSortingCanFilterByLocationAndSortByDistanceFromDifferentPointWDocQuery(t, driver) 280 spatialSortingCanSortByDistanceWOFiltering(t, driver) 281 spatialSortingCanSortByDistanceWOFilteringWDocQuery(t, driver) 282 spatialSortingCanSortByDistanceWOFilteringWDocQueryBySpecifiedField(t, driver) 283 }