2015-06-15 16 views
5

Używam spring-data-mongodb.spring-data-mongodb opcjonalny parametr zapytania

Chcę zapytać bazę danych, przekazując niektóre opcjonalne parametry w moim zapytaniu.

Mam klasę domeny.

public class Doc { 
    @Id 
    private String id; 

    private String type; 

    private String name; 

    private int index; 

    private String data; 

    private String description; 

    private String key; 

    private String username; 
    // getter & setter 
} 

Mój kontroler:

@RequestMapping(value = "/getByCategory", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) 
    public Iterable<Doc> getByCategory(
      @RequestParam(value = "key", required = false) String key, 
      @RequestParam(value = "username", required = false) String username, 
      @RequestParam(value = "page", required = false, defaultValue = "0") int page, 
      @RequestParam(value = "size", required = false, defaultValue = "0") int size, 
      @RequestParam(value = "categories") List<String> categories) 
      throws EntityNotFoundException { 
     Iterable<Doc> nodes = docService.getByCategory(key, username , categories, page, size); 
     return nodes; 
    } 

Tutaj Key i nazwa są opcjonalne parametry zapytań.

Jeśli przekażę którekolwiek z nich, powinien zwrócić odpowiedni dokument z podanym kluczem lub nazwą użytkownika.

Moja metoda usługi jest:

public Iterable<Doc> getByCategory(String key, String username, List<String> categories, int page, int size) { 

     return repository.findByCategories(key, username, categories, new PageRequest(page, size)); 
    } 

Repozytorium:

@Query("{ $or : [ {'key':?0},{'username':?1},{categories:{$in: ?2}}] }")  
List<Doc> findByCategories(String key, String username,List<String> categories, Pageable pageable); 

Ale za pomocą wyżej zapytania nie zwraca dokument z obu podany klucz lub nazwę użytkownika. Co jest nie tak w moim zapytaniu?

ten sposób robię zażądania http://localhost:8080/document/getByCategory?key=key_one&username=ppotdar&categories=category1&categories=category2

+0

Możesz zacząć ustawiać program MongoDB Profiler, aby rejestrować wszystkie operacje (a więc zapytania) za pomocą komendy 'db.setProfilingLevel (2)', a następnie zobaczyć dokładnie kwerendę, którą wykonujesz. Pamiętaj, aby po zakończeniu ustawić 0. – araknoid

Odpowiedz

0

Osobiście bym rów interfejsu napędzane repozytorium wzór w tym miejscu utworzyć DAO że @Autowire sa MongoTemplate obiekt, a następnie przy użyciu kwerendy DB zamiast tego: Criteria. w ten sposób masz czytelny kod, który nie rozszerza możliwości adnotacji @Query.

Tak, coś w tym (nietestowanego, pseudo-kod):

@Repository 
public class DocDAOImpl implements DocDAO { 
    @Autowired private MongoTemplate mongoTemplate; 

    public Page<Doc> findByCategories(UserRequest request, Pageable pageable){ 
     //Go through user request and make a criteria here 
     Criteria c = Criteria.where("foo").is(bar).and("x").is(y); 
     Query q = new Query(c); 
     Long count = mongoTemplate.count(q); 

     // Following can be refactored into another method, given the Query and the Pageable. 
     q.with(sort); //Build the sort from the pageable. 
     q.limit(limit); //Build this from the pageable too 
     List<Doc> results = mongoTemplate.find(q, Doc.class); 
     return makePage(results, pageable, count); 
    } 

    ... 
} 

Znam ten leci w obliczu tendencji do generowania wykonawczego kodu DB, ale moim zdaniem, to wciąż najlepszy podejście do trudniejszych operacji DB, ponieważ łatwiej jest zobaczyć, co się właściwie dzieje.

Powiązane problemy