geowithin
For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt
<!-- Tab options on this page. Append to the .md URL to filter: ?tabs=<id,...> select specific tabs (e.g. ?tabs=nodejs,shell) ?allTabs=true include every tab (no param) default: one tab per tabset
Available tabs: other tabs: polygon-atlas-atlas-ui, multipolygon-atlas-atlas-ui, polygon-atlas-mongosh, multipolygon-atlas-mongosh, polygon-atlas-compass, multipolygon-atlas-compass, polygon-atlas-csharp, multipolygon-atlas-csharp, polygon-atlas-go, multipolygon-atlas-go, polygon-atlas-java-sync, multipolygon-atlas-java-sync, polygon-atlas-kotlin-coroutine, multipolygon-atlas-kotlin-coroutine, polygon-atlas-nodejs, multipolygon-atlas-nodejs, polygon-atlas-python, multipolygon-atlas-python -->
geoWithin Operator
Definition
The geoWithin operator supports querying geographic points within a given geometry. Only points are returned, even if indexShapes value is true in the [index definition.](https://www.mongodb.com/docs/search/indexes/field-types/geo-type.md#std-label-bson-data-types-geo
You can query points within a:
-
Circle
-
Bounding box
-
Polygon
When specifying the coordinates to search, longitude must be specified first and then the latitude. Longitude values can be between -180 and 180, both inclusive. Latitude values can be between -90 and 90, both inclusive. Coordinate values can be integers or doubles.
Note:
MongoDB Search does not support the following:
-
Non-default coordinate reference system (CRS)
-
Planar XY coordinate system (2 dimensional)
-
Coordinate pairs Point notation (that is,
pointFieldName: [12, 34])
Syntax
geoWithin has the following syntax:
{
"$search": {
"index": <index name>, // optional, defaults to "default"
"geoWithin": {
"path": "<field-to-search>",
"box | circle | geometry": <object>,
"score": <score-options>
}
}
}
Options
geoWithin uses the following terms to construct a query:
| Field | Type | Description | Necessity |
|---|---|---|---|
box |
object | Object that specifies the bottom left and top right [GeoJSON](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson points of a box to search within. The object takes the following fields: bottomLeft - Bottom left GeoJSON [point.](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-point; topRight - Top right GeoJSON [point.](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-point To learn how to specify GeoJSON data inside a GeoJSON object, see [GeoJSON Objects.](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson Either box, circle, or geometry is required. |
conditional |
circle |
object | Object that specifies the center point and the radius in meters to search within. The object contains the following [GeoJSON](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson fields: center - Center of the circle specified as a GeoJSON [point.](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-point; radius - Radius, which is a number, specified in meters. Value must be greater than or equal to 0. To learn how to specify GeoJSON data inside a GeoJSON object, see [GeoJSON Objects.](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson Either circle, box, or geometry is required. |
conditional |
geometry |
GeoJSON object | [GeoJSON](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson object that specifies the [MultiPolygon](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-multipolygon or [Polygon](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-polygon to search within. The polygon must be specified as a closed loop where the last position is the same as the first position. When calculating geospatial results, MongoDB Search [geoShape](https://www.mongodb.com/docs/search/query/operators-collectors/geoshape.md#std-label-geoshape-ref and [geoWithin](https://www.mongodb.com/docs/search/query/operators-collectors/geowithin.md#std-label-geowithin-ref operators and MongoDB $geoIntersects operator use different geometries. This difference can be seen in how MongoDB Search and MongoDB draw polygonal edges. MongoDB Search draws polygons based on Cartesian distance, which is the shortest line between two points in the coordinate reference system. MongoDB draws polygons using the geodesic mode based on 2dsphere indexes that is built on top of a third-party library for geodesic types, or the flat mode, from 2d indexes. To learn more, see [GeoJSON Objects.](https://www.mongodb.com/docs/manual/reference/geojson/#polygon MongoDB Search and MongoDB could return different results for geospatial queries involving polygons. To learn how to specify GeoJSON data inside a GeoJSON object, see [GeoJSON Objects.](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson Either geometry, box, or circle is required. |
conditional |
path |
string or array of strings | Indexed [geo](https://www.mongodb.com/docs/search/indexes/field-types/geo-type.md#std-label-bson-data-types-geo type field or fields to search. | yes |
score |
object | Score to assign to matching search results. By default, the [score](https://www.mongodb.com/docs/search/query/score/overview.md#std-label-scoring-ref in the results is 1. You can modify the score using the following options: boost: multiply the result score by the given number.; constant: replace the result score with the given number.; function: replace the result score with the given expression. For information on using score in your query, see [Score the Documents in the Results.](https://www.mongodb.com/docs/search/query/score/overview.md#std-label-scoring-ref |
no |
Examples
The following examples use the listingsAndReviews collection in the sample_airbnb database. If you have the [sample dataset](https://www.mongodb.com/docs/manual/sample-data.md#std-label-available-sample-datasets on your cluster, you can create a custom MongoDB Search index for [geo](https://www.mongodb.com/docs/search/indexes/field-types/geo-type.md#std-label-bson-data-types-geo type and run the example queries on your cluster.
Use the following sample index definition for indexing the address.location field in the listingsAndReviews collection:
{
"mappings": {
"fields": {
"address": {
"fields": {
"location": {
"type": "geo"
}
},
"type": "document"
},
"property_type": {
"type": "token"
}
}
}
}
box Example
The following query uses the geoWithin operator with the box field to search for properties within a bounding box in Australia.
The query includes a:
-
[
$limit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit stage to limit the output to3results. -
[
$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to exclude all fields exceptnameandaddress.
Note:
You don't need to specify indexes named default in your MongoDB Search query. If your index has any other name, you must specify the index field.
Basic Example
{
"$search": {
"geoWithin": {
"path": "address.location",
"box": {
"bottomLeft": {
"type": "Point",
"coordinates": [112.467, -55.050]
},
"topRight": {
"type": "Point",
"coordinates": [168.000, -9.133]
}
}
}
}
}
Output:
SCORE: 1 _id: “10091713”
access: "You have full use of the entire studio and complete privacy during you…"
accommodates: 2
address: Object
street: "Surry Hills, NSW, Australia"
suburb: "Darlinghurst"
government_area: "Sydney"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.21554
1: -33.88029
is_location_exact: true
SCORE: 1 _id: “10108388”
access: "SECURITY Secure 24hour front-desk access with full access to the roof…"
accommodates: 2
address: Object
street: "Darlinghurst, NSW, Australia"
suburb: "Darlinghurst"
government_area: "Sydney"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.21346
1: -33.87603
is_location_exact: false
SCORE: 1 _id: “10109896”
access: "You'll access all areas except the master bedroom and spare bedrooms, …"
accommodates: 2
address: Object
street: "Rozelle, NSW, Australia"
suburb: "Lilyfield/Rozelle"
government_area: "Leichhardt"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.17956
1: -33.86296
is_location_exact: true
SCORE: 1 _id: “1016739”
access: "Included in the price is unlimited wifi, Kitchen facilities, Laundry f…"
accommodates: 2
address: Object
street: "Coogee, NSW, Australia"
suburb: "Coogee"
government_area: "Randwick"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.25541
1: -33.92398
is_location_exact: true
SCORE: 1 _id: “10209136”
access: "You will have access to kitchen, bathroom, lounge room, separate laund…"
accommodates: 2
address: Object
street: "Fairlight, NSW, Australia"
suburb: "Fairlight"
government_area: "Manly"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.26969
1: -33.79629
is_location_exact: false
SCORE: 1 _id: “10213499”
access: "Guests have access to backyard saltwater pool"
accommodates: 2
address: Object
street: "Narrabeen, NSW, Australia"
suburb: ""
government_area: "Warringah"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.29792
1: -33.71472
is_location_exact: true
SCORE: 1 _id: “10416859”
access: "There is a private, external entrance to your room. And there are sta…"
accommodates: 5
address: Object
street: "Balgowlah, NSW, Australia"
suburb: "Balgowlah"
government_area: "Manly"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.26108
1: -33.7975
is_location_exact: true
SCORE: 1 _id: “10423504”
access: "The house has a front deck and back garden area. I can be flexible wi…"
accommodates: 8
address: Object
street: "Bondi Beach, NSW, Australia"
suburb: "Bondi Beach"
government_area: "Waverley"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.27448
1: -33.8872
is_location_exact: false
SCORE: 1 _id: “10459480”
access: "Complete home."
accommodates: 6
address: Object
street: "Greenwich, NSW, Australia"
suburb: "Greenwich"
government_area: "Lane Cove"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.18563
1: -33.8289
is_location_exact: true
SCORE: 1 _id: “1047087”
access: "Guests come in to the studio using their own access via a side path. G…"
accommodates: 2
address: Object
street: "Marrickville, NSW, Australia"
suburb: "Marrickville"
government_area: "Marrickville"
market: "Sydney"
country: "Australia"
country_code: "AU"
location: Object
type: "Point"
coordinates: Array (2)
0: 151.15036
1: -33.90318
is_location_exact: false
db.listingsAndReviews.aggregate([
{
"$search": {
"geoWithin": {
"path": "address.location",
"box": {
"bottomLeft": {
"type": "Point",
"coordinates": [112.467, -55.050]
},
"topRight": {
"type": "Point",
"coordinates": [168.000, -9.133]
}
}
}
}
},
{
"$limit": 3
},
{
"$project": {
"_id": 0,
"name": 1,
"address": 1
}
}
])
Output:
[
{
name: 'Surry Hills Studio - Your Perfect Base in Sydney',
address: {
street: 'Surry Hills, NSW, Australia',
suburb: 'Darlinghurst',
government_area: 'Sydney',
market: 'Sydney',
country: 'Australia',
country_code: 'AU',
location: {
type: 'Point',
coordinates: [ 151.21554, -33.88029 ],
is_location_exact: true
}
}
},
{
name: 'Sydney Hyde Park City Apartment (checkin from 6am)',
address: {
street: 'Darlinghurst, NSW, Australia',
suburb: 'Darlinghurst',
government_area: 'Sydney',
market: 'Sydney',
country: 'Australia',
country_code: 'AU',
location: {
type: 'Point',
coordinates: [ 151.21346, -33.87603 ],
is_location_exact: false
}
}
},
{
name: "THE Place to See Sydney's FIREWORKS",
address: {
street: 'Rozelle, NSW, Australia',
suburb: 'Lilyfield/Rozelle',
government_area: 'Leichhardt',
market: 'Sydney',
country: 'Australia',
country_code: 'AU',
location: {
type: 'Point',
coordinates: [ 151.17956, -33.86296 ],
is_location_exact: true
}
}
}
]
To learn how to run the following queries in the MongoDB Compass, see [Define Your Query.](https://www.mongodb.com/docs/search/about/searching.md#std-label-atlas-search-queries
| Pipeline Stage | Query |
|---|---|
$search |
`{ |
| “geoWithin”: { | |
| “path”: “address.location”, | |
| “box”: { | |
| “bottomLeft”: { | |
| “type”: “Point”, | |
| “coordinates”: [112.467, -55.050] | |
| }, | |
| “topRight”: { | |
| “type”: “Point”, | |
| “coordinates”: [168.000, -9.133] | |
| } | |
| } | |
| } | |
| }` | |
$limit |
3 |
$project |
`{ |
| “_id”: 0, | |
| “name”: 1, | |
| “address”: 1 | |
| }` |
{
"name" : "Surry Hills Studio - Your Perfect Base in Sydney",
"address" : {
"street" : "Surry Hills, NSW, Australia",
"suburb" : "Darlinghurst",
"government_area" : "Sydney",
"market" : "Sydney",
"country" : "Australia",
"country_code" : "AU",
"location" : {
"type" : "Point",
"coordinates" : [ 151.21554, -33.88029 ],
"is_location_exact" : true
}
}
}
{
"name" : "Sydney Hyde Park City Apartment (checkin from 6am)",
"address" : {
"street" : "Darlinghurst, NSW, Australia",
"suburb" : "Darlinghurst",
"government_area" : "Sydney",
"market" : "Sydney",
"country" : "Australia",
"country_code" : "AU",
"location" : {
"type" : "Point",
"coordinates" : [ 151.21346, -33.87603 ],
"is_location_exact" : false
}
}
}
{
"name" : "THE Place to See Sydney's FIREWORKS",
"address" : {
"street" : "Rozelle, NSW, Australia",
"suburb" : "Lilyfield/Rozelle",
"government_area" : "Leichhardt",
"market" : "Sydney",
"country" : "Australia",
"country_code" : "AU",
"location" : {
"type" : "Point",
"coordinates" : [ 151.17956, -33.86296 ],
"is_location_exact" : true
}
}
}
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Driver;
using MongoDB.Driver.GeoJsonObjectModel;
using MongoDB.Driver.Search;
public class GeoBoxQuery
{
// Make sure your password is URL encoded if it contains special characters
// Replace with your actual connection string with correct credentials
private const string MongoConnectionString = "<connection-string>";
public static void Main(string[] args)
{
// allow automapping of the camelCase database fields to our PropertyDocument
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
// connect to your Atlas cluster
var mongoClient = new MongoClient(MongoConnectionString);
var airbnbDatabase = mongoClient.GetDatabase("sample_airbnb");
var listingsCollection = airbnbDatabase.GetCollection<PropertyDocument>("listingsAndReviews");
// define and run pipeline
var results = listingsCollection.Aggregate()
.Search(Builders<PropertyDocument>.Search.GeoWithin(
property => property.Address!.Location,
new GeoWithinBox<GeoJson2DCoordinates>(
new GeoJsonPoint<GeoJson2DCoordinates>(new GeoJson2DCoordinates(112.467, -55.050)),
new GeoJsonPoint<GeoJson2DCoordinates>(new GeoJson2DCoordinates(168.000, -9.133))
)
))
.Limit(3)
.Project<PropertyDocument>(Builders<PropertyDocument>.Projection
.Include(property => property.Name)
.Include(property => property.Address)
.Exclude(property => property.Id))
.ToList();
// print results
foreach (var property in results)
{
Console.WriteLine(property.ToJson());
}
}
}
[BsonIgnoreExtraElements]
public class PropertyDocument
{
[BsonIgnoreIfDefault]
public ObjectId Id { get; set; }
public string? Name { get; set; }
public AddressDocument? Address { get; set; }
}
[BsonIgnoreExtraElements]
public class AddressDocument
{
public GeoJsonPoint<GeoJson2DCoordinates>? Location { get; set; }
public string? Street { get; set; }
public string? Country { get; set; }
}
Output:
{ "name" : "Surry Hills Studio - Your Perfect Base in Sydney", "address" : { "location" : { "type" : "Point", "coordinates" : [151.21554, -33.880290000000002], "is_location_exact" : true }, "street" : "Surry Hills, NSW, Australia", "country" : "Australia" } }
{ "name" : "Sydney Hyde Park City Apartment (checkin from 6am)", "address" : { "location" : { "type" : "Point", "coordinates" : [151.21346, -33.87603], "is_location_exact" : false }, "street" : "Darlinghurst, NSW, Australia", "country" : "Australia" } }
{ "name" : "THE Place to See Sydney's FIREWORKS", "address" : { "location" : { "type" : "Point", "coordinates" : [151.17956000000001, -33.862960000000001], "is_location_exact" : true }, "street" : "Rozelle, NSW, Australia", "country" : "Australia" } }
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)
// define structure of listingsAndReviews collection
type Property struct {
Name string `bson:"name"`
Address struct {
Location struct {
Type string `bson:"type"`
Coordinates []float64 `bson:"coordinates"`
} `bson:"location"`
Street string `bson:"street"`
Country string `bson:"country"`
} `bson:"address"`
}
func main() {
var err error
// connect to the Atlas cluster
ctx := context.Background()
client, err := mongo.Connect(options.Client().SetTimeout(5*time.Second).ApplyURI("<connection-string>"))
if err != nil {
panic(err)
}
defer client.Disconnect(ctx)
// set namespace
collection := client.Database("sample_airbnb").Collection("listingsAndReviews")
// define pipeline
searchStage := bson.D{{Key: "$search", Value: bson.M{
"geoWithin": bson.M{
"path": "address.location",
"box": bson.M{
"bottomLeft": bson.M{
"type": "Point",
"coordinates": []float64{112.467, -55.050},
},
"topRight": bson.M{
"type": "Point",
"coordinates": []float64{168.000, -9.133},
},
},
},
}}}
limitStage := bson.D{{Key: "$limit", Value: 3}}
projectStage := bson.D{{Key: "$project", Value: bson.D{{Key: "_id", Value: 0}, {Key: "name", Value: 1}, {Key: "address", Value: 1}}}}
// run pipeline
cursor, err := collection.Aggregate(ctx, mongo.Pipeline{searchStage, limitStage, projectStage})
if err != nil {
panic(err)
}
// print results
var results []Property
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
fmt.Println(result)
}
}
Output:
{Surry Hills Studio - Your Perfect Base in Sydney {{Point [151.21554 -33.88029]} Surry Hills, NSW, Australia Australia}}
{Sydney Hyde Park City Apartment (checkin from 6am) {{Point [151.21346 -33.87603]} Darlinghurst, NSW, Australia Australia}}
{THE Place to See Sydney's FIREWORKS {{Point [151.17956 -33.86296]} Rozelle, NSW, Australia Australia}}
import java.util.Arrays;
import static com.mongodb.client.model.Aggregates.limit;
import static com.mongodb.client.model.Aggregates.project;
import static com.mongodb.client.model.Projections.excludeId;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class GeoBoxQuery {
public static void main( String[] args ) {
// define query
Document agg = new Document("$search",
new Document("geoWithin",
new Document("path", "address.location")
.append("box",
new Document("bottomLeft",
new Document("type", "Point")
.append("coordinates", Arrays.asList(112.467, -55.050)))
.append("topRight",
new Document("type", "Point")
.append("coordinates", Arrays.asList(168.000, -9.133))))));
// specify connection
String uri = "<connection-string>";
// establish connection and set namespace
try (MongoClient mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("sample_airbnb");
MongoCollection<Document> collection = database.getCollection("listingsAndReviews");
// run query and print results
collection.aggregate(Arrays.asList(agg,
limit(3),
project(fields(excludeId(), include("name", "address")))))
.forEach(doc -> System.out.println(doc.toJson()));
}
}
}
Output:
{
"name" : "Surry Hills Studio - Your Perfect Base in Sydney",
"address" : {
"street" : "Surry Hills, NSW, Australia",
"suburb" : "Darlinghurst",
"government_area" : "Sydney",
"market" : "Sydney",
"country" : "Australia",
"country_code" : "AU",
"location" : {
"type" : "Point",
"coordinates" : [ 151.21554, -33.88029 ],
"is_location_exact" : true
}
}
}
{
"name" : "Sydney Hyde Park City Apartment (checkin from 6am)",
"address" : {
"street" : "Darlinghurst, NSW, Australia",
"suburb" : "Darlinghurst",
"government_area" : "Sydney",
"market" : "Sydney",
"country" : "Australia",
"country_code" : "AU",
"location" : {
"type" : "Point",
"coordinates" : [ 151.21346, -33.87603 ],
"is_location_exact" : false
}
}
}
{
"name" : "THE Place to See Sydney's FIREWORKS",
"address" : {
"street" : "Rozelle, NSW, Australia",
"suburb" : "Lilyfield/Rozelle",
"government_area" : "Leichhardt",
"market" : "Sydney",
"country" : "Australia",
"country_code" : "AU",
"location" : {
"type" : "Point",
"coordinates" : [ 151.17956, -33.86296 ],
"is_location_exact" : true
}
}
}
import com.mongodb.client.model.Aggregates.limit
import com.mongodb.client.model.Aggregates.project
import com.mongodb.client.model.Projections.*
import com.mongodb.kotlin.client.coroutine.MongoClient
import kotlinx.coroutines.runBlocking
import org.bson.Document
fun main() {
// establish connection and set namespace
val uri = "<connection-string>"
val mongoClient = MongoClient.create(uri)
val database = mongoClient.getDatabase("sample_airbnb")
val collection = database.getCollection<Document>("listingsAndReviews")
runBlocking {
// define query
val agg = Document(
"\$search",
Document("geoWithin",
Document("path", "address.location")
.append("box",
Document("bottomLeft",
Document("type", "Point")
.append("coordinates", listOf(112.467, -55.050)))
.append("topRight",
Document("type", "Point")
.append("coordinates", listOf(168.000, -9.133)))))
)
// run query and print results
val resultsFlow = collection.aggregate<Document>(
listOf(
agg,
limit(3),
project(fields(excludeId(), include("name", "address")))
)
)
resultsFlow.collect { println(it) }
}
mongoClient.close()
}
Output:
Document{{name=Surry Hills Studio - Your Perfect Base in Sydney, address=Document{{street=Surry Hills, NSW, Australia, suburb=Darlinghurst, government_area=Sydney, market=Sydney, country=Australia, country_code=AU, location=Document{{type=Point, coordinates=[151.21554, -33.88029], is_location_exact=true}}}}}}
Document{{name=Sydney Hyde Park City Apartment (checkin from 6am), address=Document{{street=Darlinghurst, NSW, Australia, suburb=Darlinghurst, government_area=Sydney, market=Sydney, country=Australia, country_code=AU, location=Document{{type=Point, coordinates=[151.21346, -33.87603], is_location_exact=false}}}}}}
Document{{name=THE Place to See Sydney's FIREWORKS, address=Document{{street=Rozelle, NSW, Australia, suburb=Lilyfield/Rozelle, government_area=Leichhardt, market=Sydney, country=Australia, country_code=AU, location=Document{{type=Point, coordinates=[151.17956, -33.86296], is_location_exact=true}}}}}}
const { MongoClient } = require("mongodb");
// connect to your Atlas cluster
const uri = "<connection-string>";
const client = new MongoClient(uri);
async function run() {
try {
await client.connect();
// set namespace
const database = client.db("sample_airbnb");
const coll = database.collection("listingsAndReviews");
// define pipeline
const agg = [
{
'$search': {
'geoWithin': {
'path': 'address.location',
'box': {
'bottomLeft': {
'type': 'Point',
'coordinates': [112.467, -55.050]
},
'topRight': {
'type': 'Point',
'coordinates': [168.000, -9.133]
}
}
}
}
}, {
'$limit': 3
}, {
'$project': {
'_id': 0,
'name': 1,
'address': 1
}
}
];
// run pipeline
const result = coll.aggregate(agg);
// print results
await result.forEach((doc) => console.log(doc));
} finally {
await client.close();
}
}
run().catch(console.dir);
Output:
{
name: 'Surry Hills Studio - Your Perfect Base in Sydney',
address: {
street: 'Surry Hills, NSW, Australia',
suburb: 'Darlinghurst',
government_area: 'Sydney',
market: 'Sydney',
country: 'Australia',
country_code: 'AU',
location: { type: 'Point', coordinates: [Array], is_location_exact: true }
}
}
{
name: 'Sydney Hyde Park City Apartment (checkin from 6am)',
address: {
street: 'Darlinghurst, NSW, Australia',
suburb: 'Darlinghurst',
government_area: 'Sydney',
market: 'Sydney',
country: 'Australia',
country_code: 'AU',
location: { type: 'Point', coordinates: [Array], is_location_exact: false }
}
}
{
name: "THE Place to See Sydney's FIREWORKS",
address: {
street: 'Rozelle, NSW, Australia',
suburb: 'Lilyfield/Rozelle',
government_area: 'Leichhardt',
market: 'Sydney',
country: 'Australia',
country_code: 'AU',
location: { type: 'Point', coordinates: [Array], is_location_exact: true }
}
}
import pymongo
import dns.resolver
## connect to your Atlas cluster
client = pymongo.MongoClient("<connection-string>")
## define pipeline
pipeline = [
{
"$search": {
"geoWithin": {
"path": "address.location",
"box": {
"bottomLeft": {
"type": "Point",
"coordinates": [112.467, -55.050]
},
"topRight": {
"type": "Point",
"coordinates": [168.000, -9.133]
}
}
}
}
},
{
"$limit": 3
},
{
"$project": {
"_id": 0,
"name": 1,
"address": 1
}
}
]
## run pipeline
result = client.sample_airbnb.listingsAndReviews.aggregate(pipeline)
## print results
for i in result:
print(i)
Output:
{'name': 'Surry Hills Studio - Your Perfect Base in Sydney', 'address': {'street': 'Surry Hills, NSW, Australia', 'suburb': 'Darlinghurst', 'government_area': 'Sydney', 'market': 'Sydney', 'country': 'Australia', 'country_code': 'AU', 'location': {'type': 'Point', 'coordinates': [151.21554, -33.88029], 'is_location_exact': True}}}
{'name': 'Sydney Hyde Park City Apartment (checkin from 6am)', 'address': {'street': 'Darlinghurst, NSW, Australia', 'suburb': 'Darlinghurst', 'government_area': 'Sydney', 'market': 'Sydney', 'country': 'Australia', 'country_code': 'AU', 'location': {'type': 'Point', 'coordinates': [151.21346, -33.87603], 'is_location_exact': False}}}
{'name': "THE Place to See Sydney's FIREWORKS", 'address': {'street': 'Rozelle, NSW, Australia', 'suburb': 'Lilyfield/Rozelle', 'government_area': 'Leichhardt', 'market': 'Sydney', 'country': 'Australia', 'country_code': 'AU', 'location': {'type': 'Point', 'coordinates': [151.17956, -33.86296], 'is_location_exact': True}}}
Metadata Example
{
"$searchMeta": {
"facet": {
"operator": {
"geoWithin": {
"path": "address.location",
"box": {
"bottomLeft": {
"type": "Point",
"coordinates": [112.467, -55.050]
},
"topRight": {
"type": "Point",
"coordinates": [168.000, -9.133]
}
}
}
},
"facets": {
"propertyTypeFacet": {
"type": "string",
"path": "property_type"
}
}
}
}
}
Output:
map[
count:map[lowerBound:610]
facet:map[
propertyTypeFacet:map[
buckets:[
map[_id:Apartment count:334]
map[_id:House count:168]
map[_id:Townhouse count:29]
map[_id:Guest suite count:20]
map[_id:Condominium count:11]
map[_id:Cabin count:8]
map[_id:Serviced apartment count:7]
map[_id:Villa count:7]
map[_id:Bungalow count:5]
map[_id:Guesthouse count:5]
]
]
]
]
db.listingsAndReviews.aggregate([
{
"$searchMeta": {
"facet": {
"operator": {
"geoWithin": {
"path": "address.location",
"box": {
"bottomLeft": {
"type": "Point",
"coordinates": [112.467, -55.050]
},
"topRight": {
"type": "Point",
"coordinates": [168.000, -9.133]
}
}
}
},
"facets": {
"propertyTypeFacet": {
"type": "string",
"path": "property_type"
}
}
}
}
}
])
Output:
map[
count:map[lowerBound:610]
facet:map[
propertyTypeFacet:map[
buckets:[
map[_id:Apartment count:334]
map[_id:House count:168]
map[_id:Townhouse count:29]
map[_id:Guest suite count:20]
map[_id:Condominium count:11]
map[_id:Cabin count:8]
map[_id:Serviced apartment count:7]
map[_id:Villa count:7]
map[_id:Bungalow count:5]
map[_id:Guesthouse count:5]
]
]
]
]
// establish connection and set namespace
using MongoDB.Bson;
using MongoDB.Driver;
var client = new MongoClient("<connection-string>");
var database = client.GetDatabase("sample_airbnb");
var collection = database.GetCollection<BsonDocument>("listingsAndReviews");
// define query
var agg = new BsonDocument("$searchMeta",
new BsonDocument("facet",
new BsonDocument
{
["operator"] = new BsonDocument("geoWithin",
new BsonDocument
{
["path"] = "address.location",
["box"] = new BsonDocument
{
["bottomLeft"] = new BsonDocument
{
["type"] = "Point",
["coordinates"] = new BsonArray { 112.467, -55.050 }
},
["topRight"] = new BsonDocument
{
["type"] = "Point",
["coordinates"] = new BsonArray { 168.000, -9.133 }
}
}
}),
["facets"] = new BsonDocument("propertyTypeFacet",
new BsonDocument
{
["type"] = "string",
["path"] = "property_type"
})
}));
// run query and print results
var cursor = collection.Aggregate<BsonDocument>(
new BsonDocument[] { agg }
);
foreach (var result in cursor.ToEnumerable())
{
Console.WriteLine(result);
}
Output:
map[
count:map[lowerBound:610]
facet:map[
propertyTypeFacet:map[
buckets:[
map[_id:Apartment count:334]
map[_id:House count:168]
map[_id:Townhouse count:29]
map[_id:Guest suite count:20]
map[_id:Condominium count:11]
map[_id:Cabin count:8]
map[_id:Serviced apartment count:7]
map[_id:Villa count:7]
map[_id:Bungalow count:5]
map[_id:Guesthouse count:5]
]
]
]
]
// run-geo-box-metadata-query.go
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
// establish connection and set namespace
client, err := mongo.Connect(context.TODO(),
options.Client().ApplyURI("<connection-string>"))
if err != nil {
log.Fatal(err)
}
defer client.Disconnect(context.TODO())
collection := client.Database("sample_airbnb").Collection("listingsAndReviews")
// define query
searchStage := bson.D{{"$searchMeta", bson.D{
{"facet", bson.D{
{"operator", bson.D{
{"geoWithin", bson.D{
{"path", "address.location"},
{"box", bson.D{
{"bottomLeft", bson.D{
{"type", "Point"},
{"coordinates", bson.A{112.467, -55.050}},
}},
{"topRight", bson.D{
{"type", "Point"},
{"coordinates", bson.A{168.000, -9.133}},
}},
}},
}},
}},
{"facets", bson.D{
{"propertyTypeFacet", bson.D{
{"type", "string"},
{"path", "property_type"},
}},
}},
}},
}}}
// run query and print results
cursor, err := collection.Aggregate(context.TODO(), mongo.Pipeline{searchStage})
if err != nil {
log.Fatal(err)
}
defer cursor.Close(context.TODO())
for cursor.Next(context.TODO()) {
var result bson.M
if err := cursor.Decode(&result); err != nil {
log.Fatal(err)
}
fmt.Println(result)
}
}
Output:
map[
count:map[lowerBound:610]
facet:map[
propertyTypeFacet:map[
buckets:[
map[_id:Apartment count:334]
map[_id:House count:168]
map[_id:Townhouse count:29]
map[_id:Guest suite count:20]
map[_id:Condominium count:11]
map[_id:Cabin count:8]
map[_id:Serviced apartment count:7]
map[_id:Villa count:7]
map[_id:Bungalow count:5]
map[_id:Guesthouse count:5]
]
]
]
]
import org.bson.Document;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import java.util.Arrays;
public class GeoBoxMetadataQuery {
public static void main(String[] args) {
// establish connection and set namespace
String uri = "<connection-string>";
try (MongoClient mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("sample_airbnb");
MongoCollection<Document> collection = database.getCollection("listingsAndReviews");
// define query
Document agg = new Document("$searchMeta",
new Document("facet",
new Document()
.append("operator", new Document("geoWithin",
new Document()
.append("path", "address.location")
.append("box", new Document()
.append("bottomLeft", new Document()
.append("type", "Point")
.append("coordinates", Arrays.asList(112.467, -55.050)))
.append("topRight", new Document()
.append("type", "Point")
.append("coordinates", Arrays.asList(168.000, -9.133))))))
.append("facets", new Document("propertyTypeFacet",
new Document()
.append("type", "string")
.append("path", "property_type")))));
// run query and print results
collection.aggregate(Arrays.asList(agg))
.forEach(doc -> System.out.println(doc.toJson()));
}
}
}
Output:
map[
count:map[lowerBound:610]
facet:map[
propertyTypeFacet:map[
buckets:[
map[_id:Apartment count:334]
map[_id:House count:168]
map[_id:Townhouse count:29]
map[_id:Guest suite count:20]
map[_id:Condominium count:11]
map[_id:Cabin count:8]
map[_id:Serviced apartment count:7]
map[_id:Villa count:7]
map[_id:Bungalow count:5]
map[_id:Guesthouse count:5]
]
]
]
]
import com.mongodb.client.model.Aggregates.limit
import com.mongodb.client.model.Aggregates.project
import com.mongodb.client.model.Projections.*
import com.mongodb.kotlin.client.coroutine.MongoClient
import kotlinx.coroutines.runBlocking
import org.bson.Document
fun main() {
// establish connection and set namespace
val uri = "<connection-string>"
val mongoClient = MongoClient.create(uri)
val database = mongoClient.getDatabase("sample_airbnb")
val collection = database.getCollection<Document>("listingsAndReviews")
runBlocking {
// define query
val agg = Document(
"\$searchMeta",
Document("facet",
Document("operator",
Document("geoWithin",
Document("path", "address.location")
.append("box",
Document("bottomLeft",
Document("type", "Point")
.append("coordinates", listOf(112.467, -55.050)))
.append("topRight",
Document("type", "Point")
.append("coordinates", listOf(168.000, -9.133))))))
.append("facets",
Document("propertyTypeFacet",
Document("type", "string")
.append("path", "property_type"))))
)
// run query and print results
val resultsFlow = collection.aggregate<Document>(listOf(agg))
resultsFlow.collect { println(it) }
}
mongoClient.close()
}
Output:
Document{
{count=Document{{lowerBound=610}},
facet=Document{
{propertyTypeFacet=Document{
{buckets=[Document{
{_id=Apartment, count=334}
},
Document{
{_id=House, count=168}},
Document{
{_id=Townhouse, count=29}},
Document{
{_id=Guest suite, count=20}
},
Document{
{_id=Condominium, count=11}
},
Document{
{_id=Cabin, count=8}
},
Document{
{_id=Serviced apartment, count=7}
}, Document{
{_id=Villa, count=7}
},
Document{
{_id=Bungalow, count=5}
},
Document{
{_id=Guesthouse, count=5}
}
]
}
}}
}}
}
// run-geo-box-metadata-query.js
// establish connection and set namespace
const { MongoClient } = require("mongodb");
const uri = "<connection-string>";
const client = new MongoClient(uri);
async function run() {
try {
const database = client.db("sample_airbnb");
const collection = database.collection("listingsAndReviews");
// define query
const agg = [
{
"$searchMeta": {
"facet": {
"operator": {
"geoWithin": {
"path": "address.location",
"box": {
"bottomLeft": {
"type": "Point",
"coordinates": [112.467, -55.050]
},
"topRight": {
"type": "Point",
"coordinates": [168.000, -9.133]
}
}
}
},
"facets": {
"propertyTypeFacet": {
"type": "string",
"path": "property_type"
}
}
}
}
}
];
// run query and print results
const result = collection.aggregate(agg);
await result.forEach((doc) => {
console.log(JSON.stringify(doc, null, 2));
});
} finally {
await client.close();
}
}
run().catch(console.dir);
Output:
map[
count:map[lowerBound:610]
facet:map[
propertyTypeFacet:map[
buckets:[
map[_id:Apartment count:334]
map[_id:House count:168]
map[_id:Townhouse count:29]
map[_id:Guest suite count:20]
map[_id:Condominium count:11]
map[_id:Cabin count:8]
map[_id:Serviced apartment count:7]
map[_id:Villa count:7]
map[_id:Bungalow count:5]
map[_id:Guesthouse count:5]
]
]
]
]
```python
run-geo-box-metadata-query.py
establish connection and set namespace
import pymongo
client = pymongo.MongoClient("<connection-string>") database = client["sample_ai
(本文超出站点单文档体积上限,已截断)
