簡體   English   中英

spring-data-mongo - 可選查詢參數?

[英]spring-data-mongo - optional query parameters?

我將 spring-data mongo 與基於 JSON 的查詢方法一起使用,並且不確定如何在搜索查詢中允許可選參數。

例如 - 說我有以下功能

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

- 但我不想應用名稱正則表達式匹配,或者如果將 NULL 值傳遞給方法,則不應用日期范圍限制。

目前看來我可能必須使用 mongoTemplate 構建查詢。

有沒有其他選擇 - 或者使用 mongoTemplate 是最好的選擇?

謝謝

為了在布爾邏輯中實現這一點,我執行以下操作並轉換為編程語言中可用的操作

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

在普通的 SQL 中,這是這樣完成的

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

在 MongoDB 中,這是通過 $where

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

我們可以通過使用 Mongo Operations 來加快速度,而不是以犧牲一些可讀性為代價構建函數的所有內容。 不幸的是不起作用。

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

所以你所擁有的是

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

這可以進一步擴展以處理 in/all 子句的數組

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

我正在將spring-data mongo與基於JSON的查詢方法一起使用,並且不確定如何在搜索查詢中允許使用可選參數。

例如-說我有以下功能

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

-但我不想應用名稱正則表達式匹配,或者如果將NULL值傳遞給方法,則不希望應用日期范圍限制。

目前看來,我可能必須使用mongoTemplate構建查詢。

有沒有其他選擇-還是使用mongoTemplate是最佳選擇?

謝謝

除了阿基米德的回答:
如果您需要匹配文檔的計數,請將$where替換為$expr

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

不直接支持根據輸入值過濾掉部分查詢。 不過,它可以使用@Query$and和運算符以及一些SpEL來完成。

interface Repo extends CrudRepository<MyItem,...> {

  @Query("""
         { $and : [ 
            ?#{T(com.example.Repo.QueryUtil).ifPresent([0], 'name')}, 
            ?#{T(com.example.Repo.QueryUtil).ifDateBetween([1], [2], 'startDate')},
            ... 
         ]}
         """)
  Page<MyItem> findDataSearchParams(String name, String city, ...)

  class QueryUtil {
    public static Document ifPresent(Object value, String property) {
      if(value == null) {
        return new Document("$expr", true); // always true
      }
      return new Document(property, value); // eq match
    }

    public static Document ifDateBetween(Object value1, Object value2, String property) {
      // ...
    }
  }

  // ...
}

無需通過T(...)類型表達式來尋址目標函數,而是編寫一個EvaluationContextExtension (有關詳細信息,請參閱: json spel ),這樣可以擺脫一遍又一遍地重復類型名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM