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有参考价值的东西,请告诉我。

以前的文章有,但几乎没有最新版本的参考文献。

参考网站

 

广告
将在 10 秒后关闭
bannerAds