【问题标题】:MongoDB geospatial index in C#C#中的MongoDB地理空间索引
【发布时间】:2011-10-23 00:32:58
【问题描述】:

我一直在尝试开始,但一次又一次地尝试使用 C# 官方驱动程序创建和查询 MongoDB。问题是如何使用地理信息创建数据。我只是没有找到答案。

代码:

MongoUrl url = new MongoUrl("mongodb://xxx.xx.x.xx/mydb");
MongoServer server = MongoServer.Create(url);
MongoDatabase database = server.GetDatabase("mydb");

BsonDocument[] batch = {
                         new BsonDocument {
                                             { "name", "Bran" },
                                             { "loc", "10, 10" }
                                         },
                                        new BsonDocument {
                                            { "name", "Ayla" },
                                            { "loc", "0, 0" }
                                        }
            };

places.InsertBatch(batch);

places.EnsureIndex(IndexKeys.GeoSpatial("loca"));
var queryplaces = Query.WithinCircle("loca", 0, 0, 11);
var cursor = places.Find(queryplaces);
foreach (var hit in cursor)
{
    foreach (var VARIABLE in hit)
    {
        Console.WriteLine(VARIABLE.Value);
    }
}

【问题讨论】:

    标签: c# mongodb geocoding geospatial mongodb-.net-driver


    【解决方案1】:

    下面的例子是在 C# 中(重要的是要注意数组中的顺序是经度,纬度 - 遵循 x,y 的更合乎逻辑的顺序,而不是纬度在经度之前的更常用的形式):

    1.) 首先你的班级需要有这个:

    public double[] Location { get; set; }
    
    public double Latitude
    {
        get { return _latitude; }
        set
        {
            Location[1] = value;
            _latitude = value;
        }
    }
    
    public double Longitude
    {
        get { return _longitude; }
        set
        {
            Location[0] = value;
            _longitude = value;
        }
    }
    
    public MyClass()
    {
        Location = new double[2];
    }
    

    2.) 那么这里有一些代码可以帮助您开始使用官方 C# 驱动程序并使用地理索引进行插入:

        /// <summary>
        /// Inserts object and creates GeoIndex on collection (assumes TDocument is a class
        /// containing an array double[] Location where [0] is the x value (as longitude)
        /// and [1] is the y value (as latitude) - this order is important for spherical queries.
        /// 
        /// Collection name is assigned as typeof(TDocument).ToString()
        /// </summary>
        /// <param name="dbName">Your target database</param>
        /// <param name="data">The object you're storing</param>
        /// <param name="geoIndexName">The name of the location based array on which to create the geoIndex</param>
        /// <param name="indexNames">optional: a dictionary containing any additional fields on which you would like to create an index
        /// where the key is the name of the field on which you would like to create your index and the value should be either SortDirection.Ascending
        /// or SortDirection.Descending. NOTE: this should not include geo indexes! </param>
        /// <returns>void</returns>
        public static void MongoGeoInsert<TDocument>(string dbName, TDocument data, string geoIndexName, Dictionary<string, SortDirection> indexNames = null)
        {
            Connection connection = new Connection(dbName);
            MongoCollection collection = connection.GetMongoCollection<TDocument>(typeof(TDocument).Name, connection.Db);
            collection.Insert<TDocument>(data);
            /* NOTE: Latitude and Longitude MUST be wrapped in separate class or array */
            IndexKeysBuilder keys = IndexKeys.GeoSpatial(geoIndexName);
            IndexOptionsBuilder options = new IndexOptionsBuilder();
            options.SetName("idx_" + typeof(TDocument).Name);
            // since the default GeoSpatial range is -180 to 180, we don't need to set anything here, but if
            // we wanted to use something other than latitude/longitude, we could do so like this:
            // options.SetGeoSpatialRange(-180.0, 180.0);
    
            if (indexNames != null)
            {
                foreach (var indexName in indexNames)
                {
                    if (indexName.Value == SortDirection.Decending)
                    {
                        keys = keys.Descending(indexName.Key);
                    }
                    else if (indexName.Value == SortDirection.Ascending)
                    {
                        keys = keys.Ascending(indexName.Key);
                    }
                }
            }
    
            collection.EnsureIndex(keys, options);
    
            connection.Db.Server.Disconnect();
        }
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using MongoDB.Bson;
    using MongoDB.Driver;
    
    namespace MyMongo.Helpers
    {
        public class Connection
        {
            private const string DbName = "";
            private const string Prefix = "mongodb://";
            //private const string Server = "(...):27017/";
            private const string Server = "localhost:27017/";
            private const string PassWord = "";
            private const string UserName = "";
            private const string Delimeter = "";
            //if using MongoHQ
            //private const string Delimeter = ":";
            //private const string Prefix = "mongodb://";
            //private const string DbName = "(...)";
            //private const string UserName = "(...)";
            //private const string Server = "@flame.mongohq.com:(<port #>)/";
            //private const string PassWord = "(...)";
            private readonly string _connectionString = string.Empty;
    
            public MongoDatabase Db { get; private set; }
            public MongoCollection Collection { get; private set; }
    
            public Connection()
            {
                _connectionString = Prefix + UserName + Delimeter + PassWord + Server + DbName;
            }
    
            public Connection(string dbName)
            {
                _connectionString = Prefix + UserName + Delimeter + PassWord + Server + DbName;
                Db = GetDatabase(dbName);
            }
    
            //mongodb://[username:password@]hostname[:port][/[database][?options]]
            public MongoDatabase GetDatabase(string dbName)
            {
                MongoServer server = MongoServer.Create(_connectionString);
                MongoDatabase database = server.GetDatabase(dbName);
                return database;
            }
    
            public MongoCollection<TDocument> GetMongoCollection<TDocument>(string collectionName, MongoDatabase db, SafeMode safeMode = null)
            {
                if (safeMode == null) { safeMode = new SafeMode(true); }
                MongoCollection<TDocument> result = db.GetCollection<TDocument>(collectionName, safeMode);
                return result;
            }
        }
    }
    

    【讨论】:

    • 谢谢,我觉得这个例子非常正确,但有点高级
    • 是否需要在每个插入上添加索引?还是第一次在 mongo 集合上添加索引就足够了,并且每个插入都会自动“刷新”索引?
    • @iberodev 这个答案是很久以前写的 - 我不能确定它是否仍然是最新的
    【解决方案2】:

    查找和搜索后,我在这里找到了答案:https://github.com/karlseguin/pots-importer/blob/master/PotsImporter/NodeImporter.cs

    这将与我的第一段代码一起阅读,因为它修复了它。

      MongoCollection<BsonDocument> places =
                   database.GetCollection<BsonDocument>("places");
    
                BsonDocument[] batch = {
                                           new BsonDocument { { "name", "Bran" }, { "loc", new BsonArray(new[] { 10, 10 }) } },
                                           new BsonDocument { { "name", "Ayla" }, { "loc", new BsonArray(new[] { 0, 0 }) } }
                };
    
                places.InsertBatch(batch);
    
                places.EnsureIndex(IndexKeys.GeoSpatial("loc"));
    
                var queryplaces = Query.WithinCircle("loc", 5, 5, 10);
                var cursor = places.Find(queryplaces);
                foreach (var hit in cursor)
                {
                    Console.WriteLine("in circle");
                    foreach (var VARIABLE in hit)
                    {
                        Console.WriteLine(VARIABLE.Value);
    
                    }
                }
    

    澄清一点:问题中代码的问题是位置信息不应存储为字符串,而应存储为 2 个元素 (x, y) 的数组。

    【讨论】:

      猜你喜欢
      • 2016-02-12
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 1970-01-01
      • 2011-11-12
      • 2011-10-25
      • 1970-01-01
      相关资源
      最近更新 更多