MongoDBの位置情報にJavaライブラリのMorphia(モルフィア)で取得する
前提:
-
- システムに MongoDB 4.4 以上がインストールされていること。
- Java 11 が利用できる環境であること。
在实际应用中,经常需要实现地理空间(也称为位置基础)查询,例如搜索附近的餐馆或者搜索两个地点之间的距离。
MongoDB は、オブジェクト型 geoJSON の下に位置を格納する機能を提供し、[経度、緯度] 形式の座標フィールドに対するそれらの座標を格納します。ここで、経度は [-180, 180] の間、緯度は [-90,90] の間にある必要があります。
在进入实施之前,让我们先解释一下由MongoDB提供的geoJSON类型。
1. 要点:
表示一个声明为单一位置点。
{ type: "Point", coordinates: [ 27, 67 ] }
2. 线串:
LineString 座標字段是表示现实世界路径的包含两个或更多点的数组。
该字段的声明如下:
{ type: "LineString", coordinates: [ [ 27, 67 ], [ 52, 4 ] ] }
多边形:
Polygon 座標フィールドは、線形リングの配列です。線形リングには少なくとも 4 つの座標があり、最初の座標は最後の座標と同じで、ループを形成します。線形リングの詳細については、こちらをご覧ください。
在多边形坐标上,可能包含单个线型环或多个环。
对于单个环的情况,可以声明多边形如下:
{
type: "Polygon",
coordinates: [[[2, 1], [3, 4], [5, 1], [2, 1]]]
}
4. 多点式:
在 MultiPoint 坐标中,字段是点的数组。它的定义如下:
{
type: "MultiPoint",
coordinates: [
[162.07985, 20.66911],
[126.73567, -21.59424],
[-57.94873, 0.03998]
]
}
5. 多行字符串:
在MultiLineString中,坐标字段是折线的数组。
{
type: "MultiLineString",
coordinates: [
[[162.07985, 20.66911], [163.07945, 21.56721]],
[[126.73567, -21.59424], [127.74537, -22.54623]],
[[-57.94873, 0.03998], [-58.73823, 1.12934]]
]
}
6. MultiPolygon:
在MultiPolygon中,座標字段是一个多个多边形的数组。
{
type: "MultiPolygon",
coordinates: [
[[[0.01, 0.02], [7.01, 1.03], [3.01, 5.1], [0.01, 0.02]]],
[[[2.2, 1.01], [4.02, 2.01], [3.2, 3], [2.2, 1.01]]]
]
}
7. GeometryCollection:
这是一个复杂的geoJSON对象,用于将上述几何图形存储在一个变量中。它的定义如下所示。
{
type: "GeometryCollection",
geometries: [
{
type: "MultiPoint",
coordinates: [
[162.07985, 20.66911],
[126.73567, -21.59424],
[-57.94873, 0.03998]
]
},
{
type: "MultiLineString",
coordinates: [
[[162.07985, 20.66911], [163.07945, 21.56721]],
[[126.73567, -21.59424], [127.74537, -22.54623]],
[[-57.94873, 0.03998], [-58.73823, 1.12934]]
]
},
{
type: "MultiPolygon",
coordinates: [
[[[0.01, 0.02], [7.01, 1.03], [3.01, 5.1], [0.01, 0.02]]],
[[[2.0, 1.01], [4.0, 2.0], [3.02, 3.0], [2.0, 1.01]]]
]
}
]
}
地理空間索引
在MongoDB中,需要创建地理空间索引来执行地理空间查询,就像执行文本搜索一样。
有两种类型的地理空间索引用于地理空间搜索。
二维的:
2D 索引是在二维几何平面上进行计算时使用的。本文不详细解释这些内容。通过实施,可以创建2D 索引。
db.collection.createIndex( { <location field> : "2d" } )
在location_field的字段中,处理的坐标值需要使用[lng,lat]进行注册。
2. 2dsphere: 二维球体
当执行查询/计算时,2dsphere索引用于类似地球这样的球体。可以按如下方式创建该索引,其中位置字段可以是geoJSON对象类型或传统坐标。
db.collection.createIndex( { <location_field> : "2dsphere" } )
现在让我们开始实施吧。
使用 Java 来操作 MongoDB
在使用Java操作MongoDB时,我们将使用一个叫做Morphia的库。
Morphia 是 MongoDB 的 Java 驱动程序的封装器。它作为 MongoDB 文档的对象文档模型(ODM) 的功能。最初的目标是提供与普通的 Java 对象(POJO) 简单映射的功能。目前,新版本的 Java 驱动程序直接支持此映射。此外,Morphia 还具有一些附加值的功能,如引用和基于注释的索引创建等。
请参考以下文件,其中详细说明了如何使用 geoJSON。本次仅写出必要的部分。
在开始使用之前,在Maven中添加以下内容。
<dependencies>
<dependency>
<groupId>dev.morphia.morphia</groupId>
<artifactId>morphia-core</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
以下是参考方法,用于通过2dsphere索引搜索Point数据。
// データストアを生成する
final Datastore datastore = Morphia.createDatastore(MongoClients.create(), "morphia_example");
// エンティティクラスの場所を Morphia に設定します
// パッケージの場所またはクラスを複数指定で呼び出すことができます
datastore.getMapper().mapPackage("dev.morphia.example");
// インデックスを作成する
datastore.ensureIndexes();
// locationの値に対して指定の緯度経度から最小・最大範囲を指定して検索する。
final var point = new Point(new Position(lng, lat)); // 緯度経度の指定
final var nearFilter = Filters.near("location", point);
final Map <String, Double> opts = new HashMap <>();
opts.put("$maxDistance", 2000); // 最大範囲の指定(メートル指定)
opts.put("$minDistance", 1000); // 最小範囲の指定(メートル指定)
nearFilter.applyOpts(opts);
// 結果をリスト形式で受け取る
final var tourspots = ds.find(Tourspot.class)
.filter(nearFilter)
.iterator().toList();
如果这附近没有样本源代码,我就需要自己调查并实施,所以我将它作为备忘录写了一篇文章。
如果有其他对Morphia有参考价值的东西,请告诉我。
以前的文章有,但几乎没有最新版本的参考文献。
参考网站