MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Zwróć tylko określone pola dla zapytania w Spring Data MongoDB

1. Przegląd

W przypadku korzystania z Spring Data MongoDB może być konieczne ograniczenie właściwości mapowanych z obiektu bazy danych. Zazwyczaj możemy tego potrzebować, na przykład ze względów bezpieczeństwa – aby uniknąć ujawnienia poufnych informacji przechowywanych na serwerze. Lub też, na przykład, możemy potrzebować odfiltrować część danych wyświetlanych w aplikacji internetowej.

W tym krótkim samouczku zobaczymy, jak MongoDB stosuje ograniczenia pól.

2. Ograniczenie pól MongoDB przy użyciu projekcji

MongoDB używa projekcji do określania lub ograniczania pól, które mają być zwracane z zapytania . Jeśli jednak używamy Spring Data, chcemy zastosować to za pomocą MongoTemplate lub MongoRepository .

Dlatego chcemy stworzyć przypadki testowe dla obu MongoTemplate i MongoRepository gdzie możemy zastosować ograniczenia terenowe.

3. Wdrażanie projekcji

3.1. Konfiguracja podmiotu

Najpierw utwórzmy Inwentarz klasa:

@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. Konfigurowanie repozytorium

Następnie przetestuj MongoRepository , tworzymy InventoryRepository . Użyjemy również gdzie warunek z @Query . Na przykład chcemy filtrować według stanu zapasów:

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. Dodawanie zależności Mavena

Będziemy również używać osadzonej bazy danych MongoDB. Dodajmy spring-data-mongodb i de.flapdoodle.embed.mongo zależności od naszego pom.xml plik:

<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. Przetestuj za pomocą MongoRepository i MongoTemplate

Dla MongoRepository , zobaczymy przykłady z użyciem @Query i stosowanie ograniczeń dotyczących pól, podczas gdy dla MongoTemplate , użyjemy  Zapytanie  klasa.

Postaramy się uwzględnić wszystkie różne kombinacje włączania i wykluczania. W szczególności zobaczymy, jak ograniczyć osadzone pola lub, co ciekawsze, tablice za pomocą wycinka właściwość .

Do każdego testu dodamy MongoRepository najpierw przykład, a następnie ten dla MongoTemplate .

4.1. Uwzględnij tylko pola

Zacznijmy od uwzględnienia niektórych pól. Wszystkie wykluczone będą null . Projekcja dodaje _id domyślnie:

List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusFields("A");

inventoryList.forEach(i -> {
  assertNotNull(i.getId());
  assertNotNull(i.getItem());
  assertNotNull(i.getStatus());
  assertNull(i.getSize());
  assertNull(i.getInStock());
});

Zobaczmy teraz MongoTemplate wersja:

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

4.2. Uwzględnij i wyklucz pola

Tym razem zobaczymy przykłady, które wyraźnie zawierają niektóre pola, ale wykluczają inne – w tym przypadku wykluczymy _id pole:

List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusExcludeIdFields("A");

inventoryList.forEach(i -> {
   assertNotNull(i.getItem());
   assertNotNull(i.getStatus());
   assertNull(i.getId());
   assertNull(i.getSize());
   assertNull(i.getInStock());
});

Równoważne zapytanie przy użyciu MongoTemplate byłoby:

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

4.3. Wyłącz tylko pola

Kontynuujmy, wyłączając niektóre pola. Wszystkie inne pola nie będą puste:

List<Inventory> inventoryList = inventoryRepository.findByStatusIncludeAllButStatusAndStockFields("A");

inventoryList.forEach(i -> {
  assertNotNull(i.getItem());
  assertNotNull(i.getId());
  assertNotNull(i.getSize());
  assertNull(i.getInStock());
  assertNull(i.getStatus());
});

Zobaczmy też MongoTemplate wersja:

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

4.4. Uwzględnij pola osadzone

Ponownie, uwzględnienie osadzonych pól spowoduje dodanie ich do naszego wyniku:

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());
});

Zobaczmy, jak zrobić to samo z MongoTemplate :

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

4.5. Wyklucz pola osadzone

Podobnie wykluczenie pól osadzonych sprawia, że ​​nie znajdują się one w naszym wyniku, jednak dodaje resztę pól osadzonych :

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());
});

Przyjrzyjmy się MongoTemplate wersja:

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

4.6. Uwzględnij pola osadzone w tablicy

Podobnie jak w przypadku innych pól, możemy również dodać rzut pola tablicy:

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());
});

Zaimplementujmy to samo za pomocą MongoTemplate :

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

4.7. Dołącz osadzone pola do tablicy za pomocą slice

MongoDB może używać funkcji JavaScript do ograniczania wyników tablicy – ​​na przykład pobieranie tylko ostatniego elementu tablicy za pomocą slice :

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());
});

Wykonajmy to samo zapytanie za pomocą MongoTemplate :

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

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB Ruby Driver 2.5.x Problemy z rozróżnianiem wielkości liter w nazwach hostów w zestawach replik

  2. Usuń obiekt z zagnieżdżonej tablicy według wielu kryteriów

  3. 5 sposobów na wstawianie dokumentów do MongoDB

  4. MongoDB a MySQL

  5. Jak zainstalować MongoDB 4.2 na systemach RedHat/CentOS 7?