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 to 3 results.

  • [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to exclude all fields except name and address.

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

(本文超出站点单文档体积上限,已截断)