7

我的团队需要像 DynamoDB 这样的 DBMS 来存储大量数据,主要是地点和坐标。我考虑过在 POINT 上使用一些基于 GIS 的 DBMS(如 PostGIS),但 DynamoDB 似乎非常适合我们使用。

存储坐标并快速检索特定半径内所有对象的最佳方法是什么?

在 PostGIS 中很简单,如下所示:

SELECT *
FROM places
WHERE ST_DWithin(coordinate, ST_GeomFromText('POINT(45.07085 7.68434)', 4326), 100.0);

我怎样才能在 NoSQL DBMS 中做类似的事情?

4

3 回答 3

5

我们遇到了同样的问题,我们特别使用 AWS 和 DynamoDB。我们通过使用 CloudSearch 服务解决了这个问题,每次我们在数据库中存储一些“可地理搜索”数据时,我们都会在 CloudSearch 实例中使用 lat,lon 作为过滤器来索引数据(为此,您必须对 lat 和lon 把它变成一个 uint )。

然后假设您想对特定纬度/经度和半径进行搜索,您计算相应的地理框(latmin、latmax、lonmin、lonmax)并使用特定过滤器查询您的 CloudSearch 实例以检索数据的关键模式,您然后可以查询 DynamoDB 以获取信息。

Java中的一些代码可以完成上述操作:

使用 Tyler Coles 的 com.javadocmd.simplelatlng.window 包中的 RectangularWindows,计算边界框并对 lat / lon 进行转换。

RectangularWindow rectangularWindow = new RectangularWindow(newLatLng(location.getLat().doubleValue(), location.getLon().doubleValue()), radius.doubleValue(), radius.doubleValue(), LengthUnit.KILOMETER);
latMin = (long) ((180 + rectangularWindow.getMinLatitude()) * 100000);     
latMax = (long) ((180 + rectangularWindow.getMaxLatitude()) * 100000);
lonMin = (long) ((360 + rectangularWindow.getLeftLongitude()) * 100000);
lonMax = (long) ((360 + rectangularWindow.getRightLongitude()) * 100000);

然后是对 CloudSearch 实例的查询示例:

http://[SEARCHURL]/2011-02-01/search?bq=(和 lat:22300347..22309340 (和 lon:28379282..28391589))

我不确定这是不是最好的解决方案,但这就是我们想出的

于 2012-05-24T19:52:01.737 回答
4

您可以使用 geohashing 根据字符串而不是计算来查询附近的对象。

Geohash 将允许您将节点的位置存储到“存储桶”中,然后可以通过在 dynamodb 中使用字符串作为范围或哈希键来查询这些存储桶。

这是一个很好的例子https://github.com/davetroy/geohash-js用 javascript 完成,可以很容易地用其他语言重写。

于 2012-12-20T15:08:57.253 回答
1

我目前正在自己​​研究这个主题。我正在使用 MongoDb(我知道您要求使用 DynamoDb,但您也要求使用一般 NoSql 用法),我的代码如下所示:

记录结构:

public class FrameDocument
{
    [BsonId]
    public Guid Id { get; set; }

    [BsonElement("coordinates")]
    public Point[] Polygon { get; set; }
}

public class Point
{
    [BsonElement("name")]
    public string Orientation { get; set; }

    [BsonElement("loc")]
    public double[] Location { get; set; }
}

连接和保证指标:

MongoServer server = MongoServer.Create(connectionString);
MongoDatabase database = server.GetDatabase(databaseName);
database.GetCollection(collectionName).EnsureIndex(IndexKeys.GeoSpatial("coordinates.loc"));

写作:

var items = database.GetCollection(collectionName);
items.InsertBatch(itemsToInsert);

搜索:

double[,] points; // define you search coordinates
var items = database.GetCollection<FrameDocument>(collectionName);
var query = Query.WithinPolygon("coordinates.loc", points);
var cursor = items.Find(query);
于 2012-05-23T06:32:25.577 回答