ドキュメントのクエリ

Query クラスと Criteria クラスを使用してクエリを表現できます。これらには、ltlteis などのネイティブ MongoDB オペレーター名を反映したメソッド名が付いています。Query クラスと Criteria クラスは流れるような API スタイルに従っているため、理解しやすいコードを使用しながら、複数のメソッド条件とクエリを チェーンで組み合わせることができます。読みやすさを向上させるために、静的インポートを使用すると、Query および Criteria インスタンスの作成に "new" キーワードを使用する必要がなくなります。次の例に示すように、BasicQuery を使用して、プレーンな JSON 文字列から Query インスタンスを作成することもできます。

例 1: プレーンな JSON 文字列からクエリインスタンスを作成する
BasicQuery query = new BasicQuery("{ age : { $lt : 50 }, accounts.balance : { $gt : 1000.00 }}");
List<Person> result = mongoTemplate.find(query, Person.class);

コレクション内のドキュメントのクエリ

前に、MongoTemplate で findOne および findById メソッドを使用して単一のドキュメントを取得する方法を説明しました。これらのメソッドは、単一のドメインオブジェクトを正しいメソッドで返すか、リアクティブ API を使用して単一の要素を発行する Mono を返します。ドメインオブジェクトのリストとして返されるドキュメントのコレクションをクエリすることもできます。名前と年齢を含む多数の Person オブジェクトがコレクション内のドキュメントとして保存されており、各個人が残高のある埋め込み口座ドキュメントを持っていると仮定すると、次のコードを使用してクエリを実行できます。

MongoTemplate を使用したドキュメントのクエリ
  • 命令的

  • リアクティブ

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

// ...

List<Person> result = template.query(Person.class)
  .matching(query(where("age").lt(50).and("accounts.balance").gt(1000.00d)))
  .all();
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

// ...

Flux<Person> result = template.query(Person.class)
  .matching(query(where("age").lt(50).and("accounts.balance").gt(1000.00d)))
  .all();

すべての検索メソッドは Query オブジェクトをパラメーターとして受け取ります。このオブジェクトは、クエリの実行に使用される条件とオプションを定義します。条件は、新しい Criteria オブジェクトをインスタンス化する where という名前の静的ファクトリメソッドを持つ Criteria オブジェクトを使用して指定されます。クエリを読みやすくするために、org.springframework.data.mongodb.core.query.Criteria.where および Query.query には静的インポートを使用することをお勧めします。

クエリは、指定された条件を満たす Person オブジェクトの List または Flux を返す必要があります。このセクションの残りの部分では、MongoDB で提供される演算子に対応する Criteria クラスと Query クラスのメソッドをリストします。ほとんどのメソッドは Criteria オブジェクトを返し、API に流れるようなスタイルを提供します。

Criteria クラスのメソッド

Criteria クラスは次のメソッドを提供します。これらはすべて MongoDB の演算子に対応します。

  • Criteria すべて (Object o)  $all 演算子を使用して基準を作成します

  • Criteria および (String key) 指定された key を持つ連鎖 Criteria を現在の Criteria に追加し、新しく作成された Criteria を返します。

  • Criteria andOperator (Criteria…​ criteria) 指定されたすべての条件に対して $and 演算子を使用して AND クエリを作成します (MongoDB 2.0 以降が必要です)

  • Criteria andOperator (Collection<Criteria> criteria) 指定されたすべての条件に対して $and 演算子を使用して AND クエリを作成します (MongoDB 2.0 以降が必要です)

  • Criteria elemMatch (Criteria c)  $elemMatch 演算子を使用して条件を作成します

  • Criteria が存在します (boolean b)  $exists 演算子を使用して基準を作成します

  • Criteria gt (Object o)  $gt 演算子を使用して基準を作成します

  • Criteria gte (Object o)  $gte 演算子を使用して基準を作成します

  • Criteria in (Object…​ o) 可変長引数の $in 演算子を使用して基準を作成します。

  • Criteria in (Collection<?> collection) コレクションを使用して $in 演算子を使用して基準を作成します

  • Criteria  は (Object o) フィールドマッチング ({ key:value }) を使用して基準を作成します。指定された値がドキュメントの場合、ドキュメント内のフィールドの順序と正確な同等性が重要になります。

  • Criteria lt (Object o)  $lt 演算子を使用して基準を作成します

  • Criteria lte (Object o)  $lte 演算子を使用して基準を作成します

  • Criteria mod (Number value, Number remainder)  $mod 演算子を使用して基準を作成します

  • Criteria ne (Object o)  $ne 演算子を使用して基準を作成します

  • Criteria nin (Object…​ o)  $nin 演算子を使用して基準を作成します

  • Criteria norOperator (Criteria…​ criteria) 指定されたすべての条件に対して $nor 演算子を使用して NOR クエリを作成します

  • Criteria norOperator (Collection<Criteria> criteria) 指定されたすべての条件に対して $nor 演算子を使用して NOR クエリを作成します

  •  () ではなく Criteria 直後の句に影響を与える $not メタ演算子を使用して基準を作成します

  • Criteria orOperator (Criteria…​ criteria) 指定されたすべての条件に対して $or 演算子を使用して or クエリを作成します

  • Criteria orOperator (Collection<Criteria> criteria) 指定されたすべての条件に対して $or 演算子を使用して or クエリを作成します

  • Criteria  正規表現 (String re)  $regex を使用して基準を作成します

  • Criteria sampleRate (double sampleRate)  $sampleRate 演算子を使用して条件を作成します

  • Criteria  サイズ (int s)  $size 演算子を使用して基準を作成します

  • Criteria (int t)  $type 演算子を使用して基準を作成します

  • Criteria matchingDocumentStructure (MongoJsonSchema schema) JSON スキーマの条件の $jsonSchema 演算子を使用して条件を作成します。$jsonSchema はクエリの最上位レベルにのみ適用でき、プロパティ固有ではありません。ネストされたフィールドと照合するには、スキーマの properties 属性を使用します。

  • Criteria bits() は、$bitsAllClear と同様に、MongoDB のビットごとのクエリ演算子 (英語) へのゲートウェイです。

Criteria クラスは、地理空間クエリ用に次のメソッドも提供します。

  •  (Circle circle)  内の Criteria  $geoWithin $center 演算子を使用して地理空間基準を作成します。

  •  (Box box)  内の Criteria  $geoWithin $box 操作を使用して地理空間基準を作成します。

  • CriteriawithinSphere、 (Circle circle)$geoWithin $center 演算子を使用して地理空間基準を作成します。

  • Criteria Near (Point point)  $near 操作を使用して地理空間基準を作成します

  • Criteria nearSphere (Point point)  $nearSphere$center 操作を使用して地理空間基準を作成します。これは MongoDB 1.7 以降でのみ使用できます。

  • Criteria minDistance (double minDistance) $near で使用するために、$minDistance 操作を使用して地理空間基準を作成します。

  • Criteria maxDistance (double maxDistance) $near で使用するために、$maxDistance 操作を使用して地理空間基準を作成します。

Query クラスには、特定のフィールドを選択したり、結果を制限したり並べ替えたりできる追加のメソッドがいくつかあります。

Query クラスのメソッド
  • Query addCriteria (Criteria criteria) クエリに追加の条件を追加するために使用されます

  • Field  フィールド () は、クエリ結果に含まれるフィールドを定義するために使用されます。

  • Query  制限 (int limit) は、返される結果のサイズを指定された制限に制限するために使用されます。(ページングに使用される)

  • Query  スキップ (int skip) は、結果内の指定された数のドキュメントをスキップするために使用されます。(ページングに使用される)

  • 結果の並べ替え定義を提供するために使用される Query と (Sort sort) 

  • Query と (ScrollPosition position) は、Scroll を開始または再開するためのスクロール位置 (オフセットまたはキーセットベースのページネーション) を提供するために使用されます。

テンプレート API を使用すると、結果の射影を直接使用できます。これにより、以下で説明するように、操作結果を別のドメイン型に射影しながら、クエリを特定のドメイン型にマッピングできるようになります。

class

template.query(SWCharacter.class)
    .as(Jedi.class)

結果の射影の詳細については、ドキュメントの射影セクションを参照してください。

フィールドの選択

MongoDB は、クエリによって返されたフィールドの射影 (英語) をサポートしています。射影では、名前に基づいてフィールドを含めたり除外したりできます (_id フィールドは、明示的に除外しない限り常に含められます)。

例 2: 結果フィールドの選択
public class Person {

    @Id String id;
    String firstname;

    @Field("last_name")
    String lastname;

    Address address;
}

query.fields().include("lastname");              (1)

query.fields().exclude("id").include("lastname") (2)

query.fields().include("address")                (3)

query.fields().include("address.city")           (4)
1 結果には、_id と { "last_name" : 1 } を介した last_name の両方が含まれます。
2 結果には last_name 経由 { "_id" : 0, "last_name" : 1 } のみが含まれます。
3 結果には、_id と { "address" : 1 } を介した address オブジェクト全体が含まれます。
4 結果には、_id および { "address.city" : 1 } を介した city フィールドのみを含む address オブジェクトが含まれます。

MongoDB 4.4 以降では、以下に示すようにフィールド射影に集計式を使用できます。

例 3: 式を使用した結果フィールドの計算
query.fields()
  .project(MongoExpression.create("'$toUpper' : '$last_name'"))         (1)
  .as("last_name");                                                     (2)

query.fields()
  .project(StringOperators.valueOf("lastname").toUpper())               (3)
  .as("last_name");

query.fields()
  .project(AggregationSpELExpression.expressionOf("toUpper(lastname)")) (4)
  .as("last_name");
1 ネイティブな表現を使用します。使用されるフィールド名は、データベースドキュメント内のフィールド名を参照する必要があります。
2 式の結果が投影されるフィールド名を割り当てます。結果のフィールド名はドメインモデルに対してマッピングされません。
3AggregationExpression を使用してください。ネイティブ MongoExpression 以外のフィールド名は、ドメインモデルで使用されるものにマップされます。
4SpEL を AggregationExpression とともに使用して、式関数を呼び出します。フィールド名は、ドメインモデルで使用されているものにマップされます。

@Query(fields=" … ") では、MongoDB JSON ベースのクエリメソッドとフィールドの制限に従って、Repository レベルで式フィールド射影を使用できます。

追加のクエリオプション

MongoDB は、コメントやバッチサイズなどのメタ情報をクエリに適用するさまざまな方法を提供します。Query API を直接使用する場合、これらのオプションにはいくつかの方法があります。

ヒント

インデックスヒントは、インデックス名またはそのフィールド定義を使用する 2 つの方法で適用できます。

template.query(Person.class)
    .matching(query("...").withHint("index-to-use"));

template.query(Person.class)
    .matching(query("...").withHint("{ firstname : 1 }"));

カーソルのバッチサイズ

カーソルバッチサイズは、各レスポンスバッチで返されるドキュメントの数を定義します。

Query query = query(where("firstname").is("luke"))
    .cursorBatchSize(100)

照合

次の 2 つの例に示すように、コレクション操作で照合順序を使用するには、クエリまたは操作オプションで Collation インスタンスを指定する必要があります。

Collation collation = Collation.of("de");

Query query = new Query(Criteria.where("firstName").is("Amél"))
    .collation(collation);

List<Person> results = template.find(query, Person.class);

読み取り設定

使用する ReadPreference は、以下に説明するように、実行する Query オブジェクトに直接設定できます。

template.find(Person.class)
    .matching(query(where(...)).withReadPreference(ReadPreference.secondary()))
    .all();
Query インスタンスに設定された設定は、デフォルトの ReadPreference または MongoTemplate よりも優先されます。

コメント

クエリにはコメントを付けることができ、サーバーログでの検索が容易になります。

template.find(Person.class)
    .matching(query(where(...)).comment("Use the force luke!"))
    .all();

固有値のクエリ

MongoDB は、結果として得られるドキュメントからクエリを使用して、単一フィールドの個別の値を取得する操作を提供します。結果の値は同じデータ型である必要はなく、また、この機能は単純な型に限定されません。取得の場合、変換と入力のために実際の結果の型が重要になります。次の例は、個別の値をクエリする方法を示しています。

例 4: 個別の値の取得
template.query(Person.class)  (1)
  .distinct("lastname")       (2)
  .all();                     (3)
1Person コレクションをクエリします。
2lastname フィールドの個別の値を選択します。フィールド名は、潜在的な @Field アノテーションを考慮して、ドメイン型のプロパティ宣言に従ってマップされます。
3 すべての個別の値を List または Object として取得します (明示的な結果型が指定されていないため)。

Collection または Object に個別の値を取得することは、ドメイン型のプロパティ値を決定し、結果を目的の型またはマッピング Document 構造に変換しようとするため、最も柔軟なメソッドです。

必要なフィールドのすべての値が特定の型に固定されている場合、次の例に示すように、正しく型指定された Collection を直接取得する方が便利な場合があります。

例 5: 厳密に型指定された個別の値の取得
template.query(Person.class)  (1)
  .distinct("lastname")       (2)
  .as(String.class)           (3)
  .all();                     (4)
1Person のコレクションをクエリします。
2lastname フィールドの個別の値を選択します。フィールド名は、潜在的な @Field アノテーションを考慮して、ドメイン型のプロパティ宣言に従ってマップされます。
3 取得された値は、目的のターゲット型 (この場合は String) に変換されます。保存されたフィールドにドキュメントが含まれている場合は、値をより複雑な型にマップすることもできます。
4 すべての個別の値を List または String として取得します。型を目的のターゲット型に変換できない場合、このメソッドは DataAccessException をスローします。

+= GeoSpatial クエリ

MongoDB は、$near$withingeoWithin$nearSphere などの演算子を使用して GeoSpatial クエリをサポートします。地理空間クエリに固有のメソッドは、Criteria クラスで使用できます。地理空間関連の Criteria メソッドと組み合わせて使用される形状クラス (BoxCirclePoint) もいくつかあります。

GeoSpatial クエリを MongoDB トランザクション内で使用する場合は注意が必要です。トランザクション内の特別な動作を参照してください。

GeoSpatial クエリの実行方法を理解するには、次の Venue クラス (統合テストから取得され、豊富な MappingMongoConverter に依存する) を検討してください。

会場 .java
@Document(collection="newyork")
public class Venue {

  @Id
  private String id;
  private String name;
  private double[] location;

  @PersistenceConstructor
  Venue(String name, double[] location) {
    super();
    this.name = name;
    this.location = location;
  }

  public Venue(String name, double x, double y) {
    super();
    this.name = name;
    this.location = new double[] { x, y };
  }

  public String getName() {
    return name;
  }

  public double[] getLocation() {
    return location;
  }

  @Override
  public String toString() {
    return "Venue [id=" + id + ", name=" + name + ", location="
        + Arrays.toString(location) + "]";
  }
}

Circle 内の場所を検索するには、次のクエリを使用できます。

Circle circle = new Circle(-73.99171, 40.738868, 0.01);
List<Venue> venues =
    template.find(new Query(Criteria.where("location").within(circle)), Venue.class);

球面座標を使用して Circle 内の会場を検索するには、次のクエリを使用できます。

Circle circle = new Circle(-73.99171, 40.738868, 0.003712240453784);
List<Venue> venues =
    template.find(new Query(Criteria.where("location").withinSphere(circle)), Venue.class);

Box 内の会場を検索するには、次のクエリを使用できます。

//lower-left then upper-right
Box box = new Box(new Point(-73.99756, 40.73083), new Point(-73.988135, 40.741404));
List<Venue> venues =
    template.find(new Query(Criteria.where("location").within(box)), Venue.class);

Point の近くの会場を検索するには、次のクエリを使用できます。

Point point = new Point(-73.99171, 40.738868);
List<Venue> venues =
    template.find(new Query(Criteria.where("location").near(point).maxDistance(0.01)), Venue.class);
Point point = new Point(-73.99171, 40.738868);
List<Venue> venues =
    template.find(new Query(Criteria.where("location").near(point).minDistance(0.01).maxDistance(100)), Venue.class);

球面座標を使用して Point の近くの会場を検索するには、次のクエリを使用できます。

Point point = new Point(-73.99171, 40.738868);
List<Venue> venues =
    template.find(new Query(
        Criteria.where("location").nearSphere(point).maxDistance(0.003712240453784)),
        Venue.class);

地理的に近いクエリ

2.2 にチェンジ !
MongoDB 4.2 (英語) は、以前 NearQuery を実行するために使用されていた geoNear コマンドのサポートを削除しました。

Spring Data MongoDB 2.2 MongoOperations#geoNear は、geoNear コマンドの代わりに $geoNear  集約 (英語) を使用して NearQuery を実行します。

以前はラッパー型内で返されていた計算された距離 (geoNear コマンドを使用する場合は dis ) が、結果のドキュメントに埋め込まれるようになりました。指定されたドメイン型にその名前のプロパティがすでに含まれている場合、計算された距離には、ランダムな接尾辞が付いた calculated-distance という名前が付けられます。

ターゲット型には、次に示すように、(さらに) ドメイン型に直接読み戻すために、返された距離にちなんで名付けられたプロパティが含まれる場合があります。

GeoResults<VenueWithDistanceField> = template.query(Venue.class) (1)
    .as(VenueWithDistanceField.class)                            (2)
    .near(NearQuery.near(new GeoJsonPoint(-73.99, 40.73), KILOMETERS))
    .all();
1 ターゲットコレクションと潜在的なクエリマッピングを識別するために使用されるドメイン型。
2 型 Number の dis フィールドを含むターゲット型。

MongoDB は、データベースへの地理的位置のクエリと、指定された原点からの距離の計算を同時にサポートします。地理近傍クエリを使用すると、「周囲 16 マイル以内にあるすべてのレストランを検索する」などのクエリを表現できます。これを可能にするために、MongoOperations は、次の例に示すように、引数として NearQuery (およびすでによく知られているエンティティ型とコレクション) を取る geoNear(…) メソッドを提供します。

Point location = new Point(-73.99171, 40.738868);
NearQuery query = NearQuery.near(location).maxDistance(new Distance(10, Metrics.MILES));

GeoResults<Restaurant> = operations.geoNear(query, Restaurant.class);

NearQuery ビルダー API を使用して、指定された Point の周囲 10 マイル以内にあるすべての Restaurant インスタンスを返すクエリを設定します。ここで使用されている Metrics 列挙型は、実際には他のメトリクスも距離にプラグインできるようにインターフェースを実装しています。Metric は、指定されたメトリクスの距離値をネイティブ距離に変換する乗数によってサポートされています。ここで示されているサンプルでは、10 はマイルと見なされます。組み込みメトリクス (マイルとキロメートル) の 1 つを使用すると、クエリに球面フラグが自動的に設定されます。これを回避するには、プレーンな double 値を maxDistance(…) に渡します。詳細については、NearQuery (Javadoc) および Distance の Javadoc を参照してください。

geo-near 操作は、GeoResult インスタンスをカプセル化する GeoResults ラッパーオブジェクトを返します。GeoResults をラップすると、すべての結果の平均距離にアクセスできます。単一の GeoResult オブジェクトには、見つかったエンティティと原点からの距離が含まれます。

GeoJSON のサポート

MongoDB は、地理空間データの地理 JSON (英語) および単純な (レガシー) 座標ペアをサポートします。これらの形式は、データの保存とクエリの両方に使用できます。要件と制限については、GeoJSON サポートに関する MongoDB マニュアル (英語) を参照してください。

ドメインクラスの GeoJSON 型

ドメインクラスでの地理 JSON (英語) 型の使用は簡単です。org.springframework.data.mongodb.core.geo パッケージには、GeoJsonPointGeoJsonPolygon などの型が含まれています。これらの型は、既存の org.springframework.data.geo 型を継承したものです。次の例では、GeoJsonPoint (Javadoc) を使用しています。

public class Store {

	String id;

	/**
	 * { "type" : "Point", "coordinates" : [ x, y ] }
	 */
	GeoJsonPoint location;
}

GeoJSON オブジェクトの coordinates が緯度経度のペアを表す場合、経度が最初に続き、その後に latitude が続きます。
したがって、GeoJsonPoint は getX() を経度getY() を緯度として扱います。

リポジトリクエリメソッドの GeoJSON 型

GeoJSON 型をリポジトリクエリパラメーターとして使用すると、次の例に示すように、クエリの作成時に $geometry 演算子の使用が強制されます。

public interface StoreRepository extends CrudRepository<Store, String> {

	List<Store> findByLocationWithin(Polygon polygon);  (1)

}

/*
 * {
 *   "location": {
 *     "$geoWithin": {
 *       "$geometry": {
 *         "type": "Polygon",
 *         "coordinates": [
 *           [
 *             [-73.992514,40.758934],
 *             [-73.961138,40.760348],
 *             [-73.991658,40.730006],
 *             [-73.992514,40.758934]
 *           ]
 *         ]
 *       }
 *     }
 *   }
 * }
 */
repo.findByLocationWithin(                              (2)
  new GeoJsonPolygon(
    new Point(-73.992514, 40.758934),
    new Point(-73.961138, 40.760348),
    new Point(-73.991658, 40.730006),
    new Point(-73.992514, 40.758934)));                 (3)

/*
 * {
 *   "location" : {
 *     "$geoWithin" : {
 *        "$polygon" : [ [-73.992514,40.758934] , [-73.961138,40.760348] , [-73.991658,40.730006] ]
 *     }
 *   }
 * }
 */
repo.findByLocationWithin(                              (4)
  new Polygon(
    new Point(-73.992514, 40.758934),
    new Point(-73.961138, 40.760348),
    new Point(-73.991658, 40.730006)));
1Commons 型を使用したリポジトリメソッド定義により、GeoJSON とレガシー形式の両方でリポジトリメソッドを呼び出すことができます。
2$geometry 演算子を利用するには、GeoJSON 型を使用します。
3GeoJSON ポリゴンは閉じたリングを定義する必要があることに注意してください。
4 従来の形式の $polygon 演算子を使用します。

メトリクスと距離の計算

その後、MongoDB $geoNear オペレーターにより、GeoJSON ポイントまたは従来の座標ペアの使用が許可されます。

NearQuery.near(new Point(-73.99171, 40.738868))
{
  "$geoNear": {
    //...
    "near": [-73.99171, 40.738868]
  }
}
NearQuery.near(new GeoJsonPoint(-73.99171, 40.738868))
{
  "$geoNear": {
    //...
    "near": { "type": "Point", "coordinates": [-73.99171, 40.738868] }
  }
}

構文的には異なりますが、サーバーは、コレクション内のターゲットドキュメントがどのような形式を使用しているかに関係なく、両方を問題なく受け入れます。

距離計算には大きな違いがあります。従来の形式を使用すると、地球のような球上のラジアンが操作されますが、GeoJSON 形式では Meters が使用されます。

深刻な頭痛を避けるために、Metric を目的の測定単位に設定して、距離が正しく計算されるようにしてください。

言い換えると:

以下のような 5 つのドキュメントがあると仮定します。

{
    "_id" : ObjectId("5c10f3735d38908db52796a5"),
    "name" : "Penn Station",
    "location" : { "type" : "Point", "coordinates" : [  -73.99408, 40.75057 ] }
}
{
    "_id" : ObjectId("5c10f3735d38908db52796a6"),
    "name" : "10gen Office",
    "location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
}
{
    "_id" : ObjectId("5c10f3735d38908db52796a9"),
    "name" : "City Bakery ",
    "location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
}
{
    "_id" : ObjectId("5c10f3735d38908db52796aa"),
    "name" : "Splash Bar",
    "location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
}
{
    "_id" : ObjectId("5c10f3735d38908db52796ab"),
    "name" : "Momofuku Milk Bar",
    "location" : { "type" : "Point", "coordinates" : [ -73.985839, 40.731698 ] }
}

GeoJSON を使用して、[-73.99171, 40.738868] から半径 400 メートル以内のすべてのドキュメントを取得すると、次のようになります。

例 6: GeoJSON を使用した GeoNear
{
    "$geoNear": {
        "maxDistance": 400, (1)
        "num": 10,
        "near": { type: "Point", coordinates: [-73.99171, 40.738868] },
        "spherical":true, (2)
        "key": "location",
        "distanceField": "distance"
    }
}

次の 3 つのドキュメントを返します。

{
    "_id" : ObjectId("5c10f3735d38908db52796a6"),
    "name" : "10gen Office",
    "location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
    "distance" : 0.0 (3)
}
{
    "_id" : ObjectId("5c10f3735d38908db52796a9"),
    "name" : "City Bakery ",
    "location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
    "distance" : 69.3582262492474 (3)
}
{
    "_id" : ObjectId("5c10f3735d38908db52796aa"),
    "name" : "Splash Bar",
    "location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
    "distance" : 69.3582262492474 (3)
}
1 中心点からの最大距離 (メートル)
2GeoJSON は常に球上で動作します。
3 中心点からの距離 ( メートル)

従来の座標ペアを使用する場合、前に説明したようにラジアンを操作します。そこで Metrics#KILOMETERS when constructing the `$geoNear コマンドを使います。Metric は、距離乗数が正しく設定されていることを確認します。

例 7: GeoNear とレガシー座標ペア
{
    "$geoNear": {
        "maxDistance": 0.0000627142377, (1)
        "distanceMultiplier": 6378.137, (2)
        "num": 10,
        "near": [-73.99171, 40.738868],
        "spherical":true, (3)
        "key": "location",
        "distanceField": "distance"
    }
}

GeoJSON バリアントと同様に 3 つのドキュメントを返します。

{
    "_id" : ObjectId("5c10f3735d38908db52796a6"),
    "name" : "10gen Office",
    "location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
    "distance" : 0.0 (4)
}
{
    "_id" : ObjectId("5c10f3735d38908db52796a9"),
    "name" : "City Bakery ",
    "location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
    "distance" : 0.0693586286032982 (4)
}
{
    "_id" : ObjectId("5c10f3735d38908db52796aa"),
    "name" : "Splash Bar",
    "location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
    "distance" : 0.0693586286032982 (4)
}
1 中心点からの最大距離 (ラジアン)
2 距離の乗数なので、結果の距離としてキロメートルが得られます。
3 必ず 2d_sphere インデックスを操作してください。
4 中心点からの距離 (キロメートル) - GeoJSON バリアントのメートルと一致させるには 1000 倍かかります。

全文検索

MongoDB のバージョン 2.6 以降では、$text 演算子を使用してフルテキストクエリを実行できます。フルテキストクエリに固有のメソッドと操作は、TextQuery および TextCriteria で使用できます。全文検索を行う場合、その動作と制限については MongoDB リファレンス (英語) を参照してください。

実際に全文検索を使用する前に、検索インデックスを正しく設定する必要があります。インデックス構造の作成方法の詳細については、"テキストインデックス" を参照してください。次の例は、全文検索を設定する方法を示しています。

db.foo.createIndex(
{
  title : "text",
  content : "text"
},
{
  weights : {
              title : 3
            }
}
)

coffee cake を検索するクエリは、次のように定義して実行できます。

例 8: 全文クエリ
Query query = TextQuery
  .queryText(new TextCriteria().matchingAny("coffee", "cake"));

List<Document> page = template.find(query, Document.class);

weights に従って結果を関連性によって並べ替えるには、TextQuery.sortByScore を使用します。

例 9: 全文クエリ - スコア順に並べ替え
Query query = TextQuery
  .queryText(new TextCriteria().matchingAny("coffee", "cake"))
  .sortByScore() (1)
  .includeScore(); (2)

List<Document> page = template.find(query, Document.class);
1.sort({'score': {'$meta': 'textScore'}}) をトリガーする関連性によって結果を並べ替えるには、スコアプロパティを使用します。
2TextQuery.includeScore() を使用して、計算された関連性を結果の Document に含めます。

次の例に示すように、用語の前に - を付けるか、notMatching を使用することで、検索用語を除外できます (2 行は同じ効果を持ち、冗長であることに注意してください)。

// search for 'coffee' and not 'cake'
TextQuery.queryText(new TextCriteria().matching("coffee").matching("-cake"));
TextQuery.queryText(new TextCriteria().matching("coffee").notMatching("cake"));

TextCriteria.matching は、指定された用語をそのまま受け取ります。二重引用符で囲むことによってフレーズを定義できます (たとえば、\"coffee cake\") または TextCriteria.phrase. による使用)。次の例は、フレーズを定義する両方の方法を示しています。

// search for phrase 'coffee cake'
TextQuery.queryText(new TextCriteria().matching("\"coffee cake\""));
TextQuery.queryText(new TextCriteria().phrase("coffee cake"));

TextCriteria の対応するメソッドを使用して、$caseSensitive および $diacriticSensitive のフラグを設定できます。これら 2 つのオプションのフラグは MongoDB 3.2 に導入されており、明示的に設定しない限りクエリには含まれないことに注意してください。

例示による問い合わせ

例示による問い合わせは、テンプレート API レベルのサンプルクエリの実行で使用できます。

次の抜粋は、例によってクエリを実行する方法を示しています。

入力されたクエリの例
Person probe = new Person();
probe.lastname = "stark";

Example example = Example.of(probe);

Query query = new Query(new Criteria().alike(example));
List<Person> result = template.find(query, Person.class);

デフォルトでは、Example は厳密に型指定されます。これは、マッピングされたクエリに型一致が含まれており、プローブ割り当て可能な型に制限されていることを意味します。例: デフォルトの型キー (_class) を使用する場合、クエリには (_class : { $in : [ com.acme.Person] }) などの制限があります。

UntypedExampleMatcher を使用すると、デフォルトの動作をバイパスし、型制限をスキップすることができます。フィールド名が一致する限り、次の例に示すように、ほぼすべてのドメイン型を参照作成用のプローブとして使用できます。

例 10: 型なしのクエリの例
class JustAnArbitraryClassWithMatchingFieldName {
  @Field("lastname") String value;
}

JustAnArbitraryClassWithMatchingFieldNames probe = new JustAnArbitraryClassWithMatchingFieldNames();
probe.value = "stark";

Example example = Example.of(probe, UntypedExampleMatcher.matching());

Query query = new Query(new Criteria().alike(example));
List<Person> result = template.find(query, Person.class);

null 値を ExampleSpec に含める場合、Spring Data Mongo は、ドット表記プロパティマッチングの代わりに埋め込みドキュメントマッチングを使用します。これにより、埋め込みドキュメント内のすべてのプロパティ値とプロパティの順序が正確に一致します。

単一のコレクション内にさまざまなエンティティを保存している場合、または型ヒントの書き込みをオプトアウトしている場合は、UntypedExampleMatcher が適切な選択となる可能性があります。

また、@TypeAlias を使用するには、MappingContext の積極的な初期化が必要であることに注意してください。これを行うには、読み取り操作の適切なエイリアス解決を確保するように initialEntitySet を構成します。

Spring Data MongoDB は、さまざまなマッチングオプションのサポートを提供します。

StringMatcher のオプション
マッチング 論理的な結果

DEFAULT (case-sensitive)

{"firstname" : firstname}

DEFAULT (case-insensitive)

{"firstname" : { $regex: firstname, $options: 'i'}}

EXACT (case-sensitive)

{"firstname" : { $regex: /^firstname$/}}

EXACT (case-insensitive)

{"firstname" : { $regex: /^firstname$/, $options: 'i'}}

STARTING (case-sensitive)

{"firstname" : { $regex: /^firstname/}}

STARTING (case-insensitive)

{"firstname" : { $regex: /^firstname/, $options: 'i'}}

ENDING (case-sensitive)

{"firstname" : { $regex: /firstname$/}}

ENDING (case-insensitive)

{"firstname" : { $regex: /firstname$/, $options: 'i'}}

CONTAINING (case-sensitive)

{"firstname" : { $regex: /.*firstname.*/}}

CONTAINING (case-insensitive)

{"firstname" : { $regex: /.*firstname.*/, $options: 'i'}}

REGEX (case-sensitive)

{"firstname" : { $regex: /firstname/}}

REGEX (case-insensitive)

{"firstname" : { $regex: /firstname/, $options: 'i'}}

一致する JSON スキーマについてコレクションをクエリする

次の例に示すように、スキーマを使用して、JSON スキーマで定義された特定の構造に一致するドキュメントのコレクションをクエリできます。

例 11: $jsonSchema に一致するドキュメントのクエリ
MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();

template.find(query(matchingDocumentStructure(schema)), Person.class);

Spring Data MongoDB でのスキーマサポートの詳細については、JSON スキーマセクションを参照してください。