sql >> データベース >  >> NoSQL >> MongoDB

SpringDataMongoDBのクエリに対して特定のフィールドのみを返す

    1。概要

    Spring Data MongoDBを使用する場合、データベースオブジェクトからマッピングされるプロパティを制限する必要がある場合があります。通常、これは、たとえばセキュリティ上の理由から、サーバーに保存されている機密情報の公開を回避するために必要になる場合があります。または、たとえば、Webアプリケーションに表示されるデータの一部を除外する必要がある場合もあります。

    この短いチュートリアルでは、MongoDBがフィールド制限をどのように適用するかを見ていきます。

    2。投影を使用したMongoDBフィールドの制限

    MongoDBは、Projectionを使用して、クエリから返すフィールドを指定または制限します 。ただし、Spring Dataを使用している場合は、これを MongoTemplateで適用します。 またはMongoRepository

    したがって、両方の MongoTemplateのテストケースを作成する必要があります。 およびMongoRepository フィールド制限を適用できる場所。

    3。プロジェクションの実装

    3.1。エンティティの設定

    まず、在庫を作成しましょう クラス:

    @Document(collection = "inventory")
    public class Inventory {
    
        @Id
        private String id;
        private String status;
        private Size size;
        private InStock inStock;
    
        // standard getters and setters    
    }

    3.2。リポジトリの設定

    次に、 MongoRepositoryをテストします 、 InventoryRepositoryを作成します 。 whereも使用します @Queryの条件 。たとえば、在庫ステータスをフィルタリングする必要があります:

    public interface InventoryRepository extends MongoRepository<Inventory, String> {
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1 }")
        List<Inventory> findByStatusIncludeItemAndStatusFields(String status);
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, '_id' : 0 }")
        List<Inventory> findByStatusIncludeItemAndStatusExcludeIdFields(String status);
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'status' : 0, 'inStock' : 0 }")
        List<Inventory> findByStatusIncludeAllButStatusAndStockFields(String status);
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'size.uom': 1 }")
        List<Inventory> findByStatusIncludeEmbeddedFields(String status);
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'size.uom': 0 }")
        List<Inventory> findByStatusExcludeEmbeddedFields(String status);
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'inStock.quantity': 1 }")
        List<Inventory> findByStatusIncludeEmbeddedFieldsInArray(String status);
    
        @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'inStock': { $slice: -1 } }")
        List<Inventory> findByStatusIncludeEmbeddedFieldsLastElementInArray(String status);
    
    }

    3.3。 Mavenの依存関係の追加

    EmbeddedMongoDBも使用します。 spring-data-mongodbを追加しましょう およびde.flapdoodle.embed.mongo pom.xmlへの依存関係 ファイル:

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>3.0.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <version>3.2.6</version>
        <scope>test</scope>
    </dependency>

    4。 MongoRepositoryを使用してテストする およびMongoTemplate

    MongoRepositoryの場合 、 @Queryを使用した例を示します フィールド制限を適用する MongoTemplate を使用します クエリ クラス。

    インクルードとエクスクルードのさまざまな組み合わせをすべてカバーするようにします。 特に、スライスを使用して、埋め込みフィールドまたはさらに興味深いことに配列を制限する方法を説明します。 プロパティ

    テストごとに、 MongoRepositoryを追加します 最初に例を示し、次に MongoTemplateの例を示します。 。

    4.1。フィールドのみを含める

    いくつかのフィールドを含めることから始めましょう。除外されるものはすべてnull 。投影により、_ idが追加されます デフォルト:

    List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusFields("A");
    
    inventoryList.forEach(i -> {
      assertNotNull(i.getId());
      assertNotNull(i.getItem());
      assertNotNull(i.getStatus());
      assertNull(i.getSize());
      assertNull(i.getInStock());
    });

    それでは、 MongoTemplateをチェックしてみましょう。 バージョン:

    Query query = new Query();
     query.fields()
       .include("item")
       .include("status");
    

    4.2。フィールドの包含と除外

    今回は、一部のフィールドを明示的に含み、他のフィールドを除外する例を示します。この場合、_ idを除外します。 フィールド:

    List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusExcludeIdFields("A");
    
    inventoryList.forEach(i -> {
       assertNotNull(i.getItem());
       assertNotNull(i.getStatus());
       assertNull(i.getId());
       assertNull(i.getSize());
       assertNull(i.getInStock());
    });

    MongoTemplateを使用した同等のクエリ 次のようになります:

    Query query = new Query();
    query.fields()
      .include("item")
      .include("status")
      .exclude("_id");
    

    4.3。フィールドのみを除外

    いくつかのフィールドを除外して続行しましょう。他のすべてのフィールドはnull以外になります:

    List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeAllButStatusAndStockFields("A");
    
    inventoryList.forEach(i -> {
      assertNotNull(i.getItem());
      assertNotNull(i.getId());
      assertNotNull(i.getSize());
      assertNull(i.getInStock());
      assertNull(i.getStatus());
    });

    そして、 MongoTemplateをチェックしてみましょう。 バージョン:

    Query query = new Query();
    query.fields()
      .exclude("status")
      .exclude("inStock");
    

    4.4。埋め込みフィールドを含める

    繰り返しますが、埋め込みフィールドを含めると、結果に追加されます:

    List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFields("A");
    
    inventoryList.forEach(i -> {
      assertNotNull(i.getItem());
      assertNotNull(i.getStatus());
      assertNotNull(i.getId());
      assertNotNull(i.getSize());
      assertNotNull(i.getSize().getUom());
      assertNull(i.getSize().getHeight());
      assertNull(i.getSize().getWidth());
      assertNull(i.getInStock());
    });

    MongoTemplateで同じことを行う方法を見てみましょう :

    Query query = new Query();
    query.fields()
      .include("item")
      .include("status")
      .include("size.uom");
    

    4.5。埋め込みフィールドを除外する

    同様に、埋め込みフィールドを除外すると、結果から除外されますが、残りの埋め込みフィールドが追加されます

    List<Inventory> inventoryList = inventoryRepository.findByStatusExcludeEmbeddedFields("A");
    
    inventoryList.forEach(i -> {
      assertNotNull(i.getItem());
      assertNotNull(i.getStatus());
      assertNotNull(i.getId());
      assertNotNull(i.getSize());
      assertNull(i.getSize().getUom());
      assertNotNull(i.getSize().getHeight());
      assertNotNull(i.getSize().getWidth());
      assertNotNull(i.getInStock());
    });

    MongoTemplateを見てみましょう バージョン:

    Query query = new Query();
    query.fields()
      .exclude("size.uom");
    

    4.6。埋め込みフィールドを配列に含める

    他のフィールドと同様に、配列のフィールドの射影を追加することもできます:

    List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFieldsInArray("A");
    
    inventoryList.forEach(i -> {
      assertNotNull(i.getItem());
      assertNotNull(i.getStatus());
      assertNotNull(i.getId());
      assertNotNull(i.getInStock());
      i.getInStock()
        .forEach(stock -> {
          assertNull(stock.getWareHouse());
          assertNotNull(stock.getQuantity());
         });
      assertNull(i.getSize());
    });

    MongoTemplateを使用して同じものを実装しましょう :

    Query query = new Query();
    query.fields()
      .include("item")
      .include("status")
      .include("inStock.quantity");
    

    4.7。 スライスを使用して、埋め込みフィールドを配列に含める

    MongoDBは、JavaScript関数を使用して配列の結果を制限できます。たとえば、スライスを使用して配列の最後の要素のみを取得します。 :

    List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFieldsLastElementInArray("A");
    
    inventoryList.forEach(i -> {
      assertNotNull(i.getItem());
      assertNotNull(i.getStatus());
      assertNotNull(i.getId());
      assertNotNull(i.getInStock());
      assertEquals(1, i.getInStock().size());
      assertNull(i.getSize());
    });
    

    MongoTemplateを使用して同じクエリを実行してみましょう :

    Query query = new Query();
    query.fields()
      .include("item")
      .include("status")
      .slice("inStock", -1);
    

    1. MongoDBの正規化、外部キー、および結合

    2. mongodbアグリゲーションphp

    3. Nodejs / Express-アプリの起動:express.createServer()は非推奨です

    4. Redis:ソートされたセットのスコアの合計