diff --git a/api-reference/operators/geospatial/$box.md b/api-reference/operators/geospatial/$box.md new file mode 100644 index 0000000..89bfcaf --- /dev/null +++ b/api-reference/operators/geospatial/$box.md @@ -0,0 +1,280 @@ +--- +title: $box +description: The $box operator defines a rectangular area for geospatial queries using coordinate pairs. +type: operators +category: geospatial +--- + +# $box + +The `$box` operator defines a rectangular area for geospatial queries using two coordinate pairs. It's useful for finding locations within a rectangular geographical boundary. + +## Syntax + +```javascript +{ + : { + $geoWithin: { + $box: [ + [, ], + [, ] + ] + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field`| The field containing the geospatial data | +| `lower_left`| An array of [longitude, latitude] specifying the bottom-left corner | +| `upper_right`| An array of [longitude, latitude] specifying the top-right corner | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +### Example 1: Find stores within a geographic box + +The query retrieves up to 2 stores whose location falls inside the specified rectangular bounding box defined by two corner coordinates. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 2 - Find stores within a rectangular region + +The query returns all stores that fall within the rectangular region defined by these coordinates. + +```javascript +db.stores.find( + { + location: { + $geoWithin: { + $box: [ + [-142.0012, -51.3041], // Lower left corner + [123.3403, 70.1272] // Upper right corner + ] + } + } + }, + { + name: 1, + location: 1 + } +).limit(2) +``` + +The query returns all stores that fall within the rectangular region defined by these coordinates. + +```json +[ + { + "_id": "44fdb9b9-df83-4492-8f71-b6ef648aa312", + "name": "Fourth Coffee | Storage Solution Gallery - Port Camilla", + "location": { + "lat": 78.3889, + "lon": 0.6784 + } + }, + { + "_id": "728c068a-638c-40af-9172-8ccfa7dddb49", + "name": "Contoso, Ltd. | Book Store - Lake Myron", + "location": { "lat": 29.416, "lon": 21.5231 } + } +] +``` diff --git a/api-reference/operators/geospatial/$center.md b/api-reference/operators/geospatial/$center.md new file mode 100644 index 0000000..a30c6c4 --- /dev/null +++ b/api-reference/operators/geospatial/$center.md @@ -0,0 +1,164 @@ +--- +title: $center +description: The $center operator specifies a circle using legacy coordinate pairs for $geoWithin queries. +type: operators +category: geospatial +--- + +# $center + +The `$center` operator specifies a circle using legacy coordinate pairs to be used in `$geoWithin` queries. It defines a circle for a geospatial query on a flat, Euclidean plane. + +## Syntax + +```javascript +{ + $geoWithin: { + $center: [ [ , ], ] + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `` | The x-coordinate of the circle's center point | +| `` | The y-coordinate of the circle's center point | +| `` | The radius of the circle in the same units as the coordinates | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +### Example 1 - Find stores within a circular area + +Let's find all stores within a 50-degree radius of 'First Up Consultants Microphone Bazaar' using our `stores` dataset. This query retrieves stores within a 50-degree radius of the First Up Consultants Microphone Bazaar location. + +```javascript +db.stores.find( + { + location: { + $geoWithin: { + $center: [[-112.7858, -29.1866], 50] + } + } + }, + { + name: 1, + city: 1, + location: 1, + _id: 0 + } +).limit(2) +``` + +The query returns stores within 50-degree radius, which could be useful for analyzing market coverage or planning delivery routes. + +```json +[ + { + "name": "Contoso, Ltd. | Baby Products Corner - Port Jerrold", + "location": { "lat": -72.7709, "lon": -24.3031 }, + "city": "Port Jerrold" + }, + { + "name": "VanArsdel, Ltd. | Smart Home Closet - Trystanport", + "location": { "lat": -64.5509, "lon": -28.7144 }, + "city": "Trystanport" + } +] +``` + +> [!IMPORTANT] +> The `$center` operator works on a flat, Euclidean plane. +> +> For more accurate Earth-like spherical calculations, use `$centerSphere` instead. +> +> The radius is specified in the same units as the coordinate system being used. diff --git a/api-reference/operators/geospatial/$centersphere.md b/api-reference/operators/geospatial/$centersphere.md new file mode 100644 index 0000000..01c17c8 --- /dev/null +++ b/api-reference/operators/geospatial/$centersphere.md @@ -0,0 +1,191 @@ +--- +title: $centerSphere +description: The $centerSphere operator specifies a circle using spherical geometry for $geoWithin queries. +type: operators +category: geospatial +--- + +# $centerSphere + +The `$centerSphere` operator specifies a circle using spherical geometry for `$geoWithin` queries. This operator is useful for geographic calculations that need to account for Earth's spherical shape. + +## Syntax + +```javascript +{ + $geoWithin: { + $centerSphere: [ [ , ], ] + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `` | The longitude of the circle's center point | +| `` | The latitude of the circle's center point | +| `` | The radius of the sphere in radians (divide distance in kilometers by 6371 to convert to radians) | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1: Find stores within a circular area (calculation over earth's spherical shape) + +The example query finds two stores within approximately 1,000 kilometers (radius ≈ 0.157 radians) of the Wide World Importers Headphone Corner store location. The query can help identify nearby stores for regional marketing campaigns or supply chain optimization. + +```javascript +// Convert 1000km to radians: 1000/6371 ≈ 0.157 +db.stores.find( + { + location: { + $geoWithin: { + $centerSphere: [[-82.5543, -65.105], 0.157] + } + } + }, + { + _id: 0, + name: 1, + location: 1, + city: 1 + } +).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "name": "Fourth Coffee | Electronics Bazaar - O'Keefeburgh", + "location": { "lat": -64.5856, "lon": -115.5241 }, + "city": "O'Keefeburgh" + }, + { + "name": "Boulder Innovations | Footwear Outlet - West Sybleberg", + "location": { "lat": -72.73, "lon": -60.2306 }, + "city": "West Sybleberg" + } +] +``` + +> [!IMPORTANT] +> The `$centerSphere` operator calculates distances using spherical geometry, making it more accurate for Earth-based calculations than `$center`. +> +> The radius must be specified in radians. +> +> Coordinates should be specified in the order: [longitude, latitude]. +> +> If the geographic buffer extends beyond a UTM zone or crosses the international dateline, the results may be inaccurate or unpredictable. diff --git a/api-reference/operators/geospatial/$geointersects.md b/api-reference/operators/geospatial/$geointersects.md new file mode 100644 index 0000000..95c1e39 --- /dev/null +++ b/api-reference/operators/geospatial/$geointersects.md @@ -0,0 +1,207 @@ +--- +title: $geoIntersects +description: The $geoIntersects operator selects documents whose location field intersects with a specified GeoJSON object. +type: operators +category: geospatial +--- + +# $geoIntersects + +The `$geoIntersects` operator selects documents whose location field intersects with a specified GeoJSON object. This operator is useful when you want to find stores that intersect with a specific geographical area. + +## Syntax + +```javascript +{ + : { + $geoIntersects: { + $geometry: { + type: , + coordinates: + } + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field` | The field containing the GeoJSON object | +| `type` | The GeoJSON object type (for example, "Polygon", "MultiPolygon") | +| `coordinates` | The coordinates defining the GeoJSON object | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Find stores that geographically intersect + +For better performance, start with creating the required `2dsphere` index. + +```javascript +db.stores.createIndex({ "location": "2dsphere" }) +``` + +The example query find stores that intersect with a specific polygon area using the `stores` collection. This polygon encompasses several store locations from our dataset. + +```javascript +db.stores.find( + { + location: { + $geoIntersects: { + $geometry: { + type: "Polygon", + coordinates: [[ + [-80.0, -75.0], + [-80.0, -70.0], + [-55.0, -70.0], + [-55.0, -75.0], + [-80.0, -75.0] + ]] + } + } + } + }, + { + name: 1, + location: 1 + } +).limit(2) +``` + +The query returns stores, whose locations intersect with the Polygon contour defined by the coordinates. + +```json +[ + { + "_id": "6bba7117-d180-4584-b50c-a2f843e9c9ab", + "name": "Wide World Importers | Craft Supply Mart - Heaneybury", + "location": { "lat": -64.4843, "lon": -107.7003 }, + "city": "Heaneybury" + }, + { + "_id": "2fd37663-e0ff-41d0-9c5a-3aec86285daa", + "name": "Relecloud | Cleaning Supply Closet - Patiencehaven", + "location": { "lat": -70.6077, "lon": -105.9901 }, + "city": "Patiencehaven" + } +] +``` + +The $geointersects operator is useful for the following scenarios: + +- Finding stores within a specific geographical boundary +- Identifying service coverage areas +- Planning delivery routes diff --git a/api-reference/operators/geospatial/$geometry.md b/api-reference/operators/geospatial/$geometry.md new file mode 100644 index 0000000..f67c362 --- /dev/null +++ b/api-reference/operators/geospatial/$geometry.md @@ -0,0 +1,287 @@ +--- +title: $geometry +description: The $geometry operator specifies a GeoJSON geometry for geospatial queries. +type: operators +category: geospatial +--- + +# $geometry + +The `$geometry` operator specifies a GeoJSON geometry object for geospatial queries. It's used within other geospatial operators to define shapes and points for spatial calculations. + +## Syntax + +```javascript +{ + $geometry: { + type: , + coordinates: + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `type` | GeoJSON object type (Point, Polygon, MultiPolygon, etc.) | +| `coordinates` | Coordinates defining the GeoJSON object as an array | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1: Find nearest stores to point geometry + +For better performance, start with creating the required `2dsphere` index. + +```javascript +db.stores.createIndex({ location: "2dsphere" }) +``` + +The query retrieves up to two stores closest to the point at coordinates [46.2917, -62.6354], ordered by proximity. It uses the $near operator to sort results by distance from a specific point, helping find stores that are geographically nearest to a given location. + +```javascript +db.stores.find({ + location: { + $near: { + $geometry: { + type: "Point", + coordinates: [46.2917, -62.6354] + } + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "59c355e9-586c-44f8-bbaf-a87989142119", + "name": "Relecloud | Outdoor Furniture Shop - Chetside", + "location": { "lat": 46.188, "lon": -62.2789 } + }, + { + "_id": "d3a9cc23-e6ae-4806-93ac-1ade2f624742", + "name": "VanArsdel, Ltd. | Furniture Place - North Dustinside", + "location": { "lat": 47.3426, "lon": -62.4031 } + } +] +``` + +### Example 2: Find nearest stores to polygon geometry + +This query finds up to two stores whose locations intersect with a defined rectangular polygon bounded by coordinates from [-80.0, -75.0] to [-55.0, -70.0]. + +The `$geoIntersects` operator finds stores that overlap with or touch your polygon boundaries - perfect for identifying which locations interact with a specific geographic zone, whether they're fully inside it or just crossing the edge. + +```javascript +db.stores.find({ + location: { + $geoIntersects: { + $geometry: { + type: "Polygon", + coordinates: [[ + [-80.0, -75.0], // Bottom-left + [-80.0, -70.0], // Top-left + [-55.0, -70.0], // Top-right + [-55.0, -75.0], // Bottom-right + [-80.0, -75.0] // Close polygon + ]] + } + } + } +}, { + name: 1, + location: 1, + city: 1 +}).limit(2) +``` + +The first two results returned by this query. + +```json +[ + { + "_id": "6bba7117-d180-4584-b50c-a2f843e9c9ab", + "name": "Wide World Importers | Craft Supply Mart - Heaneybury", + "location": { "lat": -64.4843, "lon": -107.7003 }, + "city": "Heaneybury" + }, + { + "_id": "2fd37663-e0ff-41d0-9c5a-3aec86285daa", + "name": "Relecloud | Cleaning Supply Closet - Patiencehaven", + "location": { "lat": -70.6077, "lon": -105.9901 }, + "city": "Patiencehaven" + } +] +``` + +### Example 3: Find nearest stores to multi-polygon geometry + +The example retrieves up to two stores whose locations fall within either of the two defined rectangular regions (MultiPolygon): one near the coordinates [120.0, -13.0] to [125.0, -10.0], and another near [44.0, -64.0] to [48.0, -61.0]. + +It uses the $geoWithin operator with a MultiPolygon geometry to search for stores enclosed by any of the specified polygons, making it useful for querying across multiple nonadjacent geographic areas simultaneously. + +```javascript +db.stores.find({ + location: { + $geoWithin: { + $geometry: { + type: "MultiPolygon", + coordinates: [ + [[ + [120.0, -13.0], + [120.0, -10.0], + [125.0, -10.0], + [125.0, -13.0], + [120.0, -13.0] + ]], + [[ + [44.0, -64.0], + [44.0, -61.0], + [48.0, -61.0], + [48.0, -64.0], + [44.0, -64.0] + ]] + ] + } + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "6d70de9c-7b83-426d-81aa-f2173f97b64d", + "name": "Fabrikam, Inc. | Footwear Haven - Port Erling", + "location": { "lat": 45.641, "lon": -118.4963 } + }, + { + "_id": "96d48224-ce10-4a61-999a-8536d442f81a", + "name": "Wide World Importers | Eyewear Bazaar - West Oletachester", + "location": { "lat": 47.3461, "lon": -61.6605 } + } +] +``` diff --git a/api-reference/operators/geospatial/$geowithin.md b/api-reference/operators/geospatial/$geowithin.md new file mode 100644 index 0000000..323a7a8 --- /dev/null +++ b/api-reference/operators/geospatial/$geowithin.md @@ -0,0 +1,298 @@ +--- +title: $geoWithin +description: The $geoWithin operator selects documents whose location field is completely within a specified geometry. +type: operators +category: geospatial +--- + +# $geoWithin + +The `$geoWithin` operator selects documents whose location field falls completely within a specified geometry. This operator supports various shape operators including `$box`, `$polygon`, `$center`, and `$geometry`. + +## Syntax + +```javascript +// Using $box +{ + : { + $geoWithin: { + $box: [ [ ], [ ] ] + } + } +} + +// Using $center +{ + : { + $geoWithin: { + $center: [ [ , ], ] + } + } +} + +// Using $geometry +{ + : { + $geoWithin: { + $geometry: { + type: , + coordinates: + } + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field` | The field containing the location coordinates | +| `$box` | Two sets of coordinates defining opposite corners of a box | +| `$center` | Center point coordinates and radius in degrees | +| `$geometry` | GeoJSON object defining the boundary | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1: Find stores defined by $box + +For getting better performance, ensure you have a `2dsphere` index. + +```javascript +db.stores.createIndex({ location: "2dsphere" }) +``` + +This query finds stores that are located within a specific rectangular area on a map, defined by a box (bounding rectangle). + +```javascript +db.stores.find({ + location: { + $geoWithin: { + $box: [ + [65.0, 65.0], // Bottom left corner + [75.0, 75.0] // Top right corner + ] + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query. + +```json +[ + { + "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74", + "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", + "location": { + "lat": 70.1272, + "lon": 69.7296, + "address": "123 Entertainment Blvd", + "city": "East Linwoodbury" + } + }, + { + "_id": "fc286536-cb94-45aa-b975-7040fde04cf7", + "name": "First Up Consultants | Medical Supply Corner - South Elnoraview", + "location": { + "lat": 72.2184, + "lon": 68.9829 + } + } +] +``` + +### Example 2: Find stores defined by $center + +The query uses a `$geoWithin` operator to find stores within a circular area defined by a center point and a radius. + +```javascript +db.stores.find({ + 'location': { + $geoWithin: { + $center: [ + [-82.5543, -65.105], // Center point (Wide World Importers location) + 5 // Radius in degrees + ] + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "3e962dd0-dffb-49d6-8a96-1d29fa1553d2", + "name": "Tailwind Traders | Book Center - Lake Marlen", + "location": { "lat": -85.4034, "lon": -65.9189 } + }, + { + "_id": "7e442816-be4c-4919-8f67-d1e9162a511f", + "name": "Proseware, Inc. | Outdoor Furniture Bargains - North Obieberg", + "location": { "lat": -84.1013, "lon": -69.5717 } + } +] +``` + +### Example 3: Find stores defined by $geometry + +This query finds up to two stores whose location falls within the defined rectangular polygon. + +```javascript +db.stores.find({ + 'location': { + $geoWithin: { + $geometry: { + type: "Polygon", + coordinates: [[ + [-85.0, -70.0], + [-85.0, -60.0], + [-75.0, -60.0], + [-75.0, -70.0], + [-85.0, -70.0] + ]] + } + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "66fd4cdd-ffc3-44b6-81d9-6d5e9c1f7f9a", + "name": "Trey Research | Health Food Center - North Michelle", + "location": { "lat": -77.9951, "lon": -62.7339 } + }, + { + "_id": "ea3f775b-f977-4827-ada4-ca7fd8ed0cd4", + "name": "VanArsdel, Ltd. | Outdoor Equipment Pantry - Port Aleenton", + "location": { "lat": -76.4516, "lon": -67.2051 } + } +] +``` diff --git a/api-reference/operators/geospatial/$maxdistance.md b/api-reference/operators/geospatial/$maxdistance.md new file mode 100644 index 0000000..8001960 --- /dev/null +++ b/api-reference/operators/geospatial/$maxdistance.md @@ -0,0 +1,158 @@ +--- +title: $maxDistance +description: The $maxDistance operator specifies the maximum distance that can exist between two points in a geospatial query. +type: operators +category: geospatial +--- + +# $maxDistance + +The `$maxDistance` operator is used in geospatial queries to specify the maximum distance (in meters) that can exist between two points. It pairs well with `$near` for radius-based location searches. + +## Syntax + +```javascript +{ + : { + $near: { + $geometry: { + type: "Point", + coordinates: [, ] + }, + $maxDistance: + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field` | The field containing the geospatial data | +| `coordinates` | An array of [longitude, latitude] specifying the center point | +| `$maxDistance`| Maximum distance in meters from the center point | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +### Example 1: Find stores near a specific location + +The query retrieves up to two stores within a 10 km radius of the given point coordinates [-77.9951, -62.7339]. + +```javascript +db.stores.find({ + location: { + $near: { + $geometry: { + type: "Point", + coordinates: [-77.9951,-62.7339] + }, + $maxDistance: 10000 // 10 kilometers in meters + } + } +}, +{ + name: 1, + location: 1 +}).limit(2) +``` + +The query returns the following result. + +```json +[ + { + "_id": "66fd4cdd-ffc3-44b6-81d9-6d5e9c1f7f9a", + "name": "Trey Research | Health Food Center - North Michelle", + "location": { "lat": -77.9951, "lon": -62.7339 } + } +] +``` diff --git a/api-reference/operators/geospatial/$mindistance.md b/api-reference/operators/geospatial/$mindistance.md new file mode 100644 index 0000000..61915f1 --- /dev/null +++ b/api-reference/operators/geospatial/$mindistance.md @@ -0,0 +1,163 @@ +--- +title: $minDistance +description: The $minDistance operator specifies the minimum distance that must exist between two points in a geospatial query. +type: operators +category: geospatial +--- + +# $minDistance + +The `$minDistance` operator is used in geospatial queries to specify the minimum distance (in meters) that must exist between two points. It's useful for finding locations outside a certain radius. + +## Syntax + +```javascript +{ + : { + $near: { + $geometry: { + type: "Point", + coordinates: [, ] + }, + $minDistance: + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|------|-------------| +| `location field` | The field containing the geospatial data | +| `coordinates` | An array of [longitude, latitude] specifying the center point | +| `$minDistance` | Minimum distance in meters from the center point | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +### Example 1: Finding stores by minimum distance from a reference Point + +The example query allow to find stores that are at least 500 kilometers away from point coordinate [69.7296, 70.1272]. + +```javascript +db.stores.find({ + location: { + $near: { + $geometry: { + type: "Point", + coordinates: [69.7296, 70.1272] // Proseware Home Entertainment Hub location + }, + $minDistance: 500000 // 500 kilometers in meters + } + } +}, +{ + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "9d9d768b-4daf-4126-af15-a963bd3b88aa", + "name": "First Up Consultants | Perfume Gallery - New Verniceshire", + "location": { "lat": 36.0762, "lon": 98.7799 } + }, + { + "_id": "76b03913-37e3-4779-b3b8-0f654c1ae3e7", + "name": "Fabrikam, Inc. | Turntable Depot - Schinnershire", + "location": { "lat": 37.5534, "lon": 81.6805 } + } +] +``` diff --git a/api-reference/operators/geospatial/$near.md b/api-reference/operators/geospatial/$near.md new file mode 100644 index 0000000..0a3a375 --- /dev/null +++ b/api-reference/operators/geospatial/$near.md @@ -0,0 +1,201 @@ +--- +title: $near +description: The $near operator returns documents with location fields that are near a specified point, sorted by distance. +type: operators +category: geospatial +--- + +# $near + +The `$near` operator returns documents whose location field is near a specified point, sorted by distance. It requires a '2dsphere' index and returns documents from nearest to farthest. + +## Syntax + +```javascript +{ + : { + $near: { + $geometry: { + type: "Point", + coordinates: [, ] + }, + $maxDistance: , + $minDistance: + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field` | The field containing the GeoJSON Point | +| `$geometry` | GeoJSON Point object specifying the center point | +| `$maxDistance` | Optional. Maximum distance in meters from the center point | +| `$minDistance` | Optional. Minimum distance in meters from the center point | + +## Prerequisite + +For better performance, start with creating the required `2dsphere` index. + +```javascript +db.stores.createIndex({ "location": "2dsphere" }) +``` + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +### Example 1: Basic proximity search + +The query retrieves the two closest stores to a specific geographic point (70.1272, 69.7296) using geospatial search. This query searches for locations closest to the given point and returns stores in ascending order of distance from the point. + +```javascript +db.stores.find({ + 'location': { + $near: { + $geometry: { + type: "Point", + coordinates: [69.7296, 70.1272] // [longitude, latitude] + } + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "3882eb86-5dd6-4701-9640-f670ccb67859", + "name": "Fourth Coffee | DJ Equipment Stop - Schuppestad", + "location": { "lat": 69.4923, "lon": 70.1851 } + }, + { + "_id": "bbec6d3e-1666-45b4-8803-8b7ef8544845", + "name": "First Up Consultants | Baby Products Bargains - South Keenan", + "location": { "lat": 69.2158, "lon": 70.3328 } + } +] +``` + +### Example 2: Using both Min and Max distance + +The query retrieves stores within a 20 km to 200 km range from a specified point and calculates their distances in kilometers. This query searches in a "donut-shaped" area - finding stores that are at least 20 meters away but no more than 200 meters from the specified point. + +```javascript +db.stores.aggregate([ + { + $geoNear: { + near: { + type: "Point", + coordinates: [70.3328, 69.2158] + }, + distanceField: "distance", + minDistance: 20, + maxDistance: 200, + spherical: true + } + }, + { + $project: { + name: 1, + location: 1, + distanceKm: { $divide: ["$distance", 1000] }, + _id: 0 + } + }, + { $limit: 2 } +]) +``` diff --git a/api-reference/operators/geospatial/$nearsphere.md b/api-reference/operators/geospatial/$nearsphere.md new file mode 100644 index 0000000..e903101 --- /dev/null +++ b/api-reference/operators/geospatial/$nearsphere.md @@ -0,0 +1,213 @@ +--- +title: $nearSphere +description: The $nearSphere operator returns documents whose location fields are near a specified point on a sphere, sorted by distance on a spherical surface. +type: operators +category: geospatial +--- + +# $nearSphere + +The `$nearSphere` operator returns documents with location fields near a specified point on a sphere, calculating distances using spherical geometry. The operator is more accurate for Earth-based calculations than `$near`. + +## Syntax + +```javascript +{ + : { + $nearSphere: { + $geometry: { + type: "Point", + coordinates: [, ] + }, + $maxDistance: , + $minDistance: + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field` | The field containing the GeoJSON Point | +| `$geometry` | GeoJSON Point object specifying the center point | +| `$maxDistance` | Optional. Maximum distance in meters on a spherical surface | +| `$minDistance` | Optional. Minimum distance in meters on a spherical surface | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +For better performance, start with creating the required `2dsphere` index. + +```javascript +db.stores.createIndex({ "location": "2dsphere" }) +``` + +### Example 1: Basic spherical search + +The query retrieves stores that are closest to a specified Point (-141.9922, 16.8331) on a spherical (Earth-like) surface. + +```javascript +db.stores.find({ + 'location': { + $nearSphere: { + $geometry: { + type: "Point", + coordinates: [-141.9922, 16.8331] + } + } + } +}, { + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "643b2756-c22d-4063-9777-0945b9926346", + "name": "Contoso, Ltd. | Outdoor Furniture Corner - Pagacfort", + "location": { + "type": "Point", + "coordinates": [152.1353, -89.8688] + } + }, + { + "_id": "daa71e60-75d4-4e03-8b45-9df59af0811f", + "name": "First Up Consultants | Handbag Corner - South Salvatore", + "location": { + "type": "Point", + "coordinates": [150.2305, -89.8431] + } + } +] +``` + +### Example 2: Complex distance analysis + +This query retrieves stores between 20 meter and 200 meter from Point (65.3765, -44.8674). The query searches in a "donut-shaped" area - finding stores that are at least 20 meters away but no more than 200 meters from the specified point. + +```javascript +db.stores.aggregate([ + { + $geoNear: { + near: { + type: "Point", + coordinates: [65.3765, -44.8674] + }, + distanceField: "sphericalDistance", + minDistance: 20, + maxDistance: 200, + spherical: true + } + }, + { + $project: { + name: 1, + location: 1, + distanceKm: { $divide: ["$sphericalDistance", 1000] }, + _id: 0 + } + }, + { + $limit: 2 + } +]) +``` + +Key difference between the operator `$nearSphere` and `$near`. + +* Former uses spherical geometry for distance calculations. +* Former is more accurate for Earth-based distance calculations. +* Former is better for applications requiring precise global distance calculations diff --git a/api-reference/operators/geospatial/$polygon.md b/api-reference/operators/geospatial/$polygon.md new file mode 100644 index 0000000..a26d3bf --- /dev/null +++ b/api-reference/operators/geospatial/$polygon.md @@ -0,0 +1,173 @@ +--- +title: $polygon +description: The $polygon operator defines a polygon for geospatial queries, allowing you to find locations within an irregular shape. +type: operators +category: geospatial +--- + +# $polygon + +The `$polygon` operator defines a polygon for geospatial queries, allowing you to find locations within an irregular shape. The operator is useful for querying locations within complex geographical boundaries. + +## Syntax + +```javascript +{ + : { + $geoWithin: { + $geometry: { + type: "Polygon", + coordinates: [ + [[, ], ..., [, ], [, ]] + ] + } + } + } +} +``` + +## Parameters + +| Parameter | Description | +|-----------|-------------| +| `location field` | The field containing the geospatial data | +| `coordinates` | An array of coordinate pairs forming the polygon. The first and last points must be identical to close the polygon | + +## Examples + +Let's understand the usage with sample json from `stores` dataset. + +```json +{ + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "name": "Lakeshore Retail | Holiday Supply Hub - Marvinfort", + "location": { "lat": -74.0427, "lon": 160.8154 }, + "staff": { "employeeCount": { "fullTime": 9, "partTime": 18 } }, + "sales": { + "salesByCategory": [ { "categoryName": "Stockings", "totalSales": 25731 } ], + "revenue": 25731 + }, + "promotionEvents": [ + { + "eventName": "Mega Savings Extravaganza", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 6, "Day": 29 }, + "endDate": { "Year": 2023, "Month": 7, "Day": 7 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 16 }, + { "categoryName": "Tree Ornaments", "discountPercentage": 8 } + ] + }, + { + "eventName": "Incredible Discount Days", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 9, "Day": 27 }, + "endDate": { "Year": 2023, "Month": 10, "Day": 4 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 11 }, + { "categoryName": "Holiday Cards", "discountPercentage": 9 } + ] + }, + { + "eventName": "Massive Deal Mania", + "promotionalDates": { + "startDate": { "Year": 2023, "Month": 12, "Day": 26 }, + "endDate": { "Year": 2024, "Month": 1, "Day": 2 } + }, + "discounts": [ + { "categoryName": "Gift Bags", "discountPercentage": 21 }, + { "categoryName": "Bows", "discountPercentage": 19 } + ] + }, + { + "eventName": "Super Saver Soiree", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 3, "Day": 25 }, + "endDate": { "Year": 2024, "Month": 4, "Day": 1 } + }, + "discounts": [ + { "categoryName": "Tree Ornaments", "discountPercentage": 15 }, + { "categoryName": "Stockings", "discountPercentage": 14 } + ] + }, + { + "eventName": "Fantastic Savings Fiesta", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 6, "Day": 23 }, + "endDate": { "Year": 2024, "Month": 6, "Day": 30 } + }, + "discounts": [ + { "categoryName": "Stockings", "discountPercentage": 24 }, + { "categoryName": "Gift Wrap", "discountPercentage": 16 } + ] + }, + { + "eventName": "Price Plunge Party", + "promotionalDates": { + "startDate": { "Year": 2024, "Month": 9, "Day": 21 }, + "endDate": { "Year": 2024, "Month": 9, "Day": 28 } + }, + "discounts": [ + { "categoryName": "Holiday Tableware", "discountPercentage": 13 }, + { "categoryName": "Holiday Cards", "discountPercentage": 11 } + ] + } + ], + "company": "Lakeshore Retail", + "city": "Marvinfort", + "storeOpeningDate": { "$date": "2024-10-01T18:24:02.586Z" }, + "lastUpdated": { "$timestamp": { "t": 1730485442, "i": 1 } }, + "storeFeatures": 38 +} +``` + +### Example 1 - Search within a polygon + +The query retrieves stores that fall inside a custom polygon region based on the coordinates provided. + +```javascript +db.stores.find({ + location: { + $geoWithin: { + $geometry: { + type: "Polygon", + coordinates: [[ + [-141.9922, 16.8331], // VanArsdel Picture Frame Store + [-112.7858, -29.1866], // First Up Consultants Microphone Bazaar + [-38.4071, -47.2548], // Fabrikam Car Accessory Outlet + [-141.9922, 16.8331] // Close the polygon by repeating first point + ]] + } + } + } +}, +{ + name: 1, + location: 1 +}).limit(2) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "4a417727-a002-4c80-a01f-bc9526b300a5", + "name": "Northwind Traders | Bed and Bath Deals - East Duane", + "location": { + "type": "Point", + "coordinates": [-46.1444, -60.9697] + } + }, + { + "_id": "1e27040c-7242-4970-8893-e5738e1bc1ca", + "name": "Northwind Traders | Seasonal Decoration Bazaar - Cassidyberg", + "location": { + "type": "Point", + "coordinates": [-44.3617, -81.2186] + } + } +] +```