$ geowithin: $ polygon не использует 2dsphere index - PullRequest
0 голосов
/ 29 октября 2018

У меня есть коллекция документов, подобная следующей:

{
    "_id" : ObjectId("5bc15f23d672e9086ca4fbac"),
    "Location" : {
        "GeoJson" : {
            "type" : "Point",
            "coordinates" : [14.4199254356, 50.0700249768]
        }
}

И у меня есть индекс, созданный следующим образом

{ Location.GeoJson2dsphere : "2dsphere" }

А теперь проблема, когда я использую $polygon для поиска, у меня есть результаты, но запрос не использует индекс, поэтому он медленный. Вот запрос

.find({"Location.GeoJson" : {
      "$geoWithin" : {
      "$polygon" : [ 
        [14.4182910543168, 50.0891393887804], 
        [14.4491901021683, 50.0891393887804], 
        [14.4491901021683, 50.0671069088523], 
        [14.4182910543168, 50.0671069088523]
      ]
    }
  }
})

Но когда я вместо этого использую $ Geometry, он использует индекс.

.find({"Location.GeoJson" : {
  "$geoWithin" : 
    {"$geometry" :
      {"type" : "Polygon",
        "coordinates" : [[ 
          [14.4182910543168, 50.0891393887804], 
          [14.4491901021683, 50.0891393887804], 
          [14.4491901021683, 50.0671069088523], 
          [14.4182910543168, 50.0671069088523],
          [14.4182910543168, 50.0891393887804]
        ]]
      }}
    }})

Есть ли причина, по которой первый запрос не использует индекс? Руководство Монго ничего не говорит об этом. Можете ли вы указать мне, что делать, чтобы использовать $ polygon для поиска по индексу, или мне нужно переписать все запросы в моем приложении, чтобы использовать $ geometry. Я использую драйвер C #, где синтаксис выглядит следующим образом:

Builders<Offer>.Filter.GeoWithinPolygon(a => a.Location.GeoJson, polygon);

Однако, это производит первый запрос, который не использует индекс.

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Хорошо, и я просто добавляю aswer в C #.

Новый запрос:

GeoJsonPolygon<GeoJson2DCoordinates> polygon;
var filter = Builders<Offer>.Filter.GeoWithin(a => a.Location.GeoJson, polygon);

И мой вспомогательный класс для прямоугольника. ToGeoJsonPolygon ():

public class Rectangle
    {
        public double StartX { get; set; }
        public double StartY { get; set; }
        public double EndX { get; set; }
        public double EndY { get; set; }

        public double[,] ToCoordinates()
        {
            var retval = new double[4, 2];
            retval[0, 0] = this.StartX;
            retval[0, 1] = this.StartY;
            retval[1, 0] = this.EndX;
            retval[1, 1] = this.StartY;
            retval[2, 0] = this.EndX;
            retval[2, 1] = this.EndY;
            retval[3, 0] = this.StartX;
            retval[3, 1] = this.EndY;

            return retval;
        }

        public GeoJsonPolygon<GeoJson2DCoordinates> ToGeoJsonPolygon()
        {
            return GeoJson.Polygon(
                GeoJson.Position(StartX, StartY),
                GeoJson.Position(EndX, StartY),
                GeoJson.Position(EndX, EndY),
                GeoJson.Position(StartX, EndY),
                GeoJson.Position(StartX, StartY));
        }
    }
0 голосов
/ 01 ноября 2018

Я не работаю на монго, поэтому не рискну догадаться, что почему (за исключением устаревших моделей данных) вводит в заблуждение новичков, но вот как Монго различает индекс infinite-flat-2d (запрос $ polygon) и индекс сферический (запрос $ geometry)

прохождение $ многоугольника нацелено на устаревший 2d-индекс, где или $ geometry нацелено на 2d-сферический индекс. Mongo разделяет эти запросы на два разных типа объектов

здесь: https://github.com/mongodb/mongo/blob/master/src/mongo/db/geo/geoparser.cpp#L785-L790

Монго говорит, что индекс 2dsphere доступен только для , хотя запрос $ geometry (не устаревший запрос $ polygon )

здесь: https://docs.mongodb.com/manual/tutorial/query-a-2dsphere-index/

Как вы заметили: Mongo очень полезен тем, что он все еще может возвращать данные, даже если вы не соответствовали вашим запросам.


Почему $ многоугольник даже вещь больше?

Mongo продолжает поддерживать несферические двумерные индексы для тех, кому нужен двумерный индекс на бесконечной плоской поверхности. Возможно, для видеоигр или для любого использования, где бесконечная плоская поверхность является достаточно хорошим приближением, чтобы избежать математики с плавающей запятой (и связанных с ней вопросов округления)

описано здесь: https://docs.mongodb.com/manual/tutorial/query-a-2d-index/

...