2015-06-15 9 views
5

Sto usando spring-data-mongodb.spring-data-mongodb parametro query opzionale

Voglio interrogare il database passando qualche parametro facoltativo nella mia query.

Ho una classe di dominio.

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 
} 

mio regolatore:

@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; 
    } 

Qui chiave e nome utente sono parametri di query opzionali.

Se si supera uno di questi, è necessario restituire il documento corrispondente con la chiave o il nome utente forniti.

Il mio metodo di servizio è:

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

Repository:

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

Ma usando sopra di query non restituisce un documento sia con data chiave o nome utente. Cosa c'è di sbagliato nella mia domanda?

Questo è come mi sto facendo richiesta http://localhost:8080/document/getByCategory?key=key_one&username=ppotdar&categories=category1&categories=category2

+0

È possibile iniziare a impostare MongoDB Profiler per registrare tutte le operazioni (e quindi le query) utilizzando il comando 'db.setProfilingLevel (2)' e quindi vedere esattamente la query che si sta eseguendo. Ricorda di impostarlo su 0 al termine. – araknoid

risposta

0

Personalmente, mi piacerebbe fosso il modello repository di interfaccia-driven a quel punto, creare un DAO che @Autowire sa oggetto MongoTemplate, e poi interrogare la DB usando a Criteria invece. in questo modo, hai un codice chiaro che non estende le capacità dell'annotazione @Query.

Quindi, qualcosa di simile (pseudo-codice non testato):

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

    ... 
} 

So che questo vola di fronte della tendenza verso la generazione runtime di codice di DB, ma a mio avviso, è ancora il migliore approccio per operazioni di DB più impegnative, perché è molto più facile vedere cosa sta realmente accadendo.