Попытка пользователя mongodb's filter.near - PullRequest
2 голосов
/ 29 мая 2019

Я пытаюсь найти ближайшие сердечки из вложенного документа mongodb. Я получаю следующее сообщение об ошибке:

Я перепробовал все, что мог придумать. Я попытался добавить индекс 2d, который тоже не сработал.

var point = GeoJson.Point(GeoJson.Geographic(38.8086, -85.1792));
var locationQuery = new FilterDefinitionBuilder<Book>().NearSphere(tag => tag.CitiesInBook[-1].Location, point,
            5000); 
var query = collection.Find(locationQuery).Limit(10); 
var a =  query.ToList();

Планировщик вернул ошибку

не удалось найти индекс для запроса $ geoNear. '

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

следующий запрос агрегации работает для встроенных городов в сущности книги. Следует отметить, что вы должны создать индекс geo2dsphere с правильным именем ключа и иметь классы c # в правильной структуре, чтобы драйвер мог сериализовать / десериализовать.

db.Book.aggregate({
    "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [
                48.857908,
                2.295243
            ]
        },
        "distanceField": "SearchResult.DistanceKM",
        "spherical": true,
        "maxDistance": NumberInt("20000"),
        "includeLocs": "SearchResult.Location"
    }
})

вышеуказанный запрос был сгенерирован следующим кодом MongoDB.Entities:

using MongoDB.Driver;
using MongoDB.Entities;
using System.Collections.Generic;

namespace StackOverflow
{
    public class Program
    {
        public class Book : Entity
        {
            public string Title { get; set; }
            public List<City> CitiesInBook { get; set; } = new List<City>();
            public SearchResult SearchResult { get; set; }
        }

        public class City
        {
            public string Name { get; set; }
            public Coordinates2D Location { get; set; }
        }

        public class SearchResult
        {
            public Coordinates2D Location { get; set; }
            public double DistanceKM { get; set; }
        }

        static void Main(string[] args)
        {
            //connect to mongodb
            new DB("test");

            //create a geo2dsphere index with key "CitiesInBook.Location"
            DB.Index<Book>()
              .Key(x => x.CitiesInBook[-1].Location, KeyType.Geo2DSphere)
              .Create();

            //create 3 locations
            var paris = new City
            {
                Name = "paris",
                Location = new Coordinates2D(48.8539241, 2.2913515)
            };
            var versailles = new City
            {
                Name = "versailles",
                Location = new Coordinates2D(48.796964, 2.137456)
            };
            var poissy = new City
            {
                Name = "poissy",
                Location = new Coordinates2D(48.928860, 2.046889)
            };

            //create a book and add two cities to it
            var book = new Book { Title = "the power of now" };
            book.CitiesInBook.Add(paris);
            book.CitiesInBook.Add(poissy);
            book.Save();

            var eiffelTower = new Coordinates2D(48.857908, 2.295243);

            //find all books that have places within 20km of eiffel tower.
            var books = DB.GeoNear<Book>(
                            NearCoordinates: eiffelTower,
                            DistanceField: b => b.SearchResult.DistanceKM,
                            IncludeLocations: b => b.SearchResult.Location,
                            MaxDistance: 20000)
                          .ToList();
        }
    }
}
0 голосов
/ 02 июня 2019

вот решение с использованием MongoDB.Entities . я использовал отношения «один ко многим» между книгой и городом вместо того, чтобы включать города в сущность книги.

using MongoDB.Driver;
using MongoDB.Entities;

namespace StackOverflow
{
    public class Program
    {
        public class Book : Entity
        {
            public string Name { get; set; }
            public Many<City> Cities { get; set; }

            public Book() => this.InitOneToMany(() => Cities);
        }

        public class City : Entity
        {
            public string Name { get; set; }
            public Coordinates2D Location { get; set; }
            public double DistanceKM { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            //create an index
            DB.Index<City>()
              .Key(c => c.Location, KeyType.Geo2DSphere)
              .Option(o => o.Background = false)
              .Create();

            var paris = new City
            {
                Name = "paris",
                Location = new Coordinates2D(48.8539241, 2.2913515)
            };
            paris.Save();

            var versailles = new City
            {
                Name = "versailles",
                Location = new Coordinates2D(48.796964, 2.137456)
            };
            versailles.Save();

            var poissy = new City
            {
                Name = "poissy",
                Location = new Coordinates2D(48.928860, 2.046889)
            };
            poissy.Save();

            var scifi = new Book { Name = "sci-fi" };
            scifi.Save();
            scifi.Cities.Add(paris);
            scifi.Cities.Add(versailles);
            scifi.Cities.Add(poissy);

            var horror = new Book { Name = "horror" };
            horror.Save();
            horror.Cities.Add(poissy);

            var eiffelTower = new Coordinates2D(48.857908, 2.295243);

            //find matching city IDs within 20kms of eiffel tower.
            var cities = DB.GeoNear<City>(
                            NearCoordinates: eiffelTower,
                            DistanceField: c => c.DistanceKM,
                            MaxDistance: 20000);

            //get books with matching cities
            var books = DB.Entity<Book>()
                          .Cities.ParentsFluent<Book>(cities)
                          .ToList();
        }
    }
}

вышеуказанная программа выдает следующий запрос агрегации на mongodb:

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

{
    "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [
                48.857908,
                2.295243
            ]
        },
        "distanceField": "DistanceKM",
        "spherical": true,
        "maxDistance": NumberInt("20000")
    }
}, {
    "$lookup": {
        "from": "[Book~City(Cities)]",
        "localField": "_id",
        "foreignField": "ChildID",
        "as": "Results"
    }
}, {
    "$replaceRoot": {
        "newRoot": {
            "$arrayElemAt": [
                "$Results",
                NumberInt("0")
            ]
        }
    }
}, {
    "$lookup": {
        "from": "Book",
        "localField": "ParentID",
        "foreignField": "_id",
        "as": "Results"
    }
}, {
    "$replaceRoot": {
        "newRoot": {
            "$arrayElemAt": [
                "$Results",
                NumberInt("0")
            ]
        }
    }
}, {
    "$group": {
        "_id": "$_id",
        "doc": {
            "$first": "$$ROOT"
        }
    }
}, {
    "$replaceRoot": {
        "newRoot": "$doc"
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...