2012-07-23 2 views
14

Sto utilizzando spring-data mongo con i metodi di query basati su JSON e non sono sicuro di come consentire i parametri facoltativi in ​​una query di ricerca.spring-data-mongo - parametri di query facoltativi?

Per esempio - dire che ho avuto la seguente funzione

@Query("{ 'name' : {$regex : ?0, $options : 'i'}, 'createdDate' : {$gte : ?1, $lt : ?2 }} }") 
List<MyItem> getItemsLikeNameByDateRange(String name, Date startDateRange, Date endDateRange); 

-ma non volevo applicare il nome regex partita, o non si applica una restrizione intervallo di date, se i valori NULL sono stati passati al metodo.

Al momento sembra che potrebbe essere necessario creare la query utilizzando il mongoTemplate.

Ci sono delle alternative - o sta usando mongoTemplate l'opzione migliore?

Grazie

+0

Per ora ho seguito il percorso dell'utilizzo delle classi di Criteri. Sembra molto più pulito dell'inclusione delle query JSON nelle annotazioni e più facile da personalizzare quali campi vengono recuperati. –

risposta

16

Per implementare questa logica booleana I effettuare le seguenti operazioni e la conversione alle operazioni che sono disponibili nei linguaggi di programmazione

:query != null -> field == :query 
!(:query != null) || (field == :query) 
(:query == null) || (field == :query) 

In SQL pianura, questo è fatto come

where (null = :query) or (field = :query) 

In MongoDB ciò avviene tramite $ dove

{ $where: '?0 == null || this.field == ?0' } 

Possiamo velocizzare questo un po 'di usando Operazioni di mongolo piuttosto che costruire tutto per la funzione a scapito di una certa leggibilità. purtroppo non funziona

{ $or : [ { $where: '?0 == null' } , { field : ?0 } ] } 

Quindi quello che hai è

@Query("{ $or : [ { $where: '?0 == null' } , { field : ?0 } ] }") 
List<Something> findAll(String query, Pageable pageable); 

Questo può essere ulteriormente ampliato per gestire gli array per in/tutte le clausole

@Query("{ $or : [ { $where: '?0.length == 0' } , { field : { $in : ?0 } } ] }") 
List<Something> findAll(String query, Pageable pageable); 
1

si potrebbe essere interessati a fornire un feedback o votare su questo numero: https://jira.springsource.org/browse/DATAJPA-209

Si tratta di exa questo problema, eccetto SD JPA. Sembra che sia appropriato per molti altri sottoprogetti SD.

+0

Grazie, votato a questo! –

0

Il biglietto fornito tratta i ricercatori che generano il loro SQL con "nome magico", ad es. findByTitleAndSubtitle(), che ora funziona correttamente. Ma c'è ancora lo stesso problema quando annoti questo finder con @Query ("seleziona prodotto dove title =: title e sottotitolo =: sottotitolo"); i valori nulli sono tradotti in "sottotitolo = null" e pertanto non verranno trovati.