我使用的是spring数据mongodb。
我想通过在查询中传递一些可选参数来查询数据库。
我有一个域类。
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
}
我的控制器:
@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;
}
这里Key和username是可选的查询参数。
如果我通过其中任何一个,它应该返回具有给定密钥或用户名的匹配文档。
我的服务方式是:
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));
}
存储库:
@Query("{ $or : [ {'key':?0},{'username':?1},{categories:{$in: ?2}}] }")
List<Doc> findByCategories(String key, String username,List<String> categories, Pageable pageable);
但是通过使用上述查询,它不会返回具有给定密钥或用户名的文档。我的查询有什么问题?
这就是我提出请求的方式http://localhost:8080/document/getByCategory?key=key_one
不直接支持根据输入值筛选出查询的部分。不过,可以使用查询($)和运算符以及一点SpEL来完成。
interface Repo extends CrudRepository<Doc,...> {
@Query("""
{ $and : [
?#{T(com.example.Repo.QueryUtil).ifPresent([0], 'key')},
?#{T(com.example.Repo.QueryUtil).ifPresent([1], 'username')},
...
]}
""")
List<Doc> findByKeyAndUsername(@Nullable String key, @Nullable String username, ...)
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
}
}
// ...
}
而不是通过T(…)寻址目标函数 类型表达式编写一个EvaluationContextExtension(详细信息请参见:json spel)可以避免重复类型名称。
就我个人而言,我会抛弃接口驱动的存储库模式,创建一个DAO,该DAO将Autowire作为MongoTemplate对象,然后使用标准查询DB。这样,您就有了清晰的代码,不会扩展查询注释的功能。
所以,像这样的东西(未经测试的伪代码):
@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);
}
...
}
我知道这与数据库代码的运行时生成趋势背道而驰,但在我看来,它仍然是更具挑战性的数据库操作的最佳方法,因为它更容易看到实际发生的事情。
是否有其他选择-或者使用mongoTemplate是最好的选择? 谢谢
问题内容: 我正在将spring-data mongo与基于JSON的查询方法一起使用,并且不确定如何在搜索查询中允许使用可选参数。 例如-说我有以下功能 -但是我不想应用名称正则表达式匹配,或者如果将NULL值传递给方法,则不希望应用日期范围限制。 目前看来,我可能必须使用mongoTemplate构建查询。 有没有其他选择-还是使用mongoTemplate是最佳选择? 谢谢 问题答案: 为了
问题内容: 我想在存储库层中编写一些查询方法。此方法必须忽略空参数。例如: 在这种情况下,此方法必须返回Foo: 如果gooParam不为null。如果gooParam为null,则条件更改为: 有什么解决办法吗?有人能帮我吗? 问题答案: 来不及了。不确定 Bar 和 Goo 之间的关系。检查 Example是否 可以帮助您。 它为我工作。我有一个类似的情况,实体 用户 具有属性集,并且有基于属
GroupIdDeliveryStatusReport的结构 如果我不能恰当地描述,请原谅我。 我就是这样写的
问题内容: 我有以下POJO。 我正在尝试实现一个查询,该查询查找包含标签列表的所有。我尝试了以下方法: 但这仅在我传递给该方法的标记的完全匹配在Mongo中分配给该问题的标记的列表时才有效。例如,如果我在Mongo中有一个带有标签列表的问题,当我传递给该方法时,它不会返回。 我也尝试了以下方法: 但是我根本无法部署到我的servlet容器。(在这种情况下,我收到以下错误消息: 您能否建议如何实施
我想用spring Boot1.5执行过滤器列表的查询,我有必需的参数(用户名)和可选的参数(电子邮件),我如何在查询中分配可选的参数?@Query(“从User u中选择u.username LIKE:username和u.email=:email”)公共页面getUsers(@param(“username”)字符串username,@param(“email”)字符串email);http: