2011-08-09 6 views
4

J'ai essayé de commencer mais couru dans la même roche après avoir essayé de créer et d'interroger MongoDB avec le pilote officiel C#. Le problème est de savoir comment créer des données avec des informations géographiques. Je ne trouve pas la réponse.MongoDB géospatial index en C#

code:

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

< - ceci fonctionne très bien

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

places.InsertBatch(batch); 

< - cette partie est en quelque sorte de mal

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); 
    } 
} 

< - Je pense qu'une partie devrait montrer les deux documents, maintenant aucun. Une simple trouvaille les montre tous les deux. Serait heureux pour de l'aide.

Répondre

2

Après avoir regardé et recherché, j'ai trouvé la réponse ici: https://github.com/karlseguin/pots-importer/blob/master/PotsImporter/NodeImporter.cs

Ceci doit être lu avec mon premier morceau de code comme cela le corrige.

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); 

       } 
      } 

Comme point de clarification: Le problème avec le code de la question est que les informations de localisation ne doit pas être stocké sous forme de chaîne, mais comme un tableau de 2 éléments (x, y).

6

exemple ci-dessous est en C# (il est important de noter l'ordre dans le tableau qui est la longitude, latitude-suit l'ordre plus logique de x, y, par opposition à la forme plus couramment utilisée lorsque la latitude précède la longitude):

1.) d'abord votre classe doit avoir ceci:

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.) puis est un code ici pour vous aider à démarrer avec le pilote officiel C# et faire un insert w/utilisation de géo indexation:

/// <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:[email protected]]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; 
     } 
    } 
} 
+0

merci, je pense que cet exemple est très correct mais un peu avancé – JustusTh