Spring data mongodb 如何使用MongoRepository查询任何字段

Spring data mongodb 如何使用MongoRepository查询任何字段,spring-data-mongodb,Spring Data Mongodb,假设域对象(MyDomain)有许多文件(f1、f2、f3…f100),从MongoRepository中定义MyDomainRepository,我想将字段名和值作为参数,而不是将字段名硬编码作为查询方法的一部分,如下所示: List<MyDomain> findByNameAndValue(string name, string value); 列出findByNameAndValue(字符串名称、字符串值); 如果名称和值为“f1”和“foo”,则该方法将查找字段“f1”等

假设域对象(MyDomain)有许多文件(f1、f2、f3…f100),从MongoRepository中定义MyDomainRepository,我想将字段名和值作为参数,而不是将字段名硬编码作为查询方法的一部分,如下所示:

List<MyDomain> findByNameAndValue(string name, string value);
列出findByNameAndValue(字符串名称、字符串值);
如果名称和值为“f1”和“foo”,则该方法将查找字段“f1”等于“foo”的所有文档

我在谷歌上搜索了好几个小时,但运气不好

任何人的帮助,谢谢

您需要使用谓词

首先,将以下依赖项添加到pom.xml(假设您使用maven构建项目):


...
com.querydsl

构建项目时,QueryDSL将为您生成Q类,您可以使用该类以编程方式构建谓词并查询与谓词匹配的文档:

QMyDomain q = QMyDomain.mydomain;
Predicate p = q.f1.eq(value);

Iterable<MydDomain> i = repository.findAll(p);
QMyDomain q=QMyDomain.mydomain;
谓词p=q.f1.eq(值);
Iterable i=repository.findAll(p);
要使用REST控制器查询资源,您需要类似以下内容:

@RestController
@RequestMapping(/"mydomain")
public class MyDomainController {

    @Autowired private MyDomainRepository repository;

    @GetMapping("/search/query")
    public List<MyDomain> query(@QuerydslPredicate(root = MyDomain.class) Predicate predicate) {
        return repository.findAll(predicate);
    }
}
@RestController
@请求映射(/“mydomain”)
公共类MyDomainController{
@自动连线私有MyDomainRepository存储库;
@GetMapping(“/search/query”)
公共列表查询(@QuerydslPredicate(root=MyDomain.class)谓词){
返回repository.findAll(谓词);
}
}
最后一段代码是快速而肮脏的,它可能不会按原样工作(至少返回某种类型的列表),但你明白了。

你需要使用谓词

首先,将以下依赖项添加到pom.xml(假设您使用maven构建项目):


...
com.querydsl

构建项目时,QueryDSL将为您生成Q类,您可以使用该类以编程方式构建谓词并查询与谓词匹配的文档:

QMyDomain q = QMyDomain.mydomain;
Predicate p = q.f1.eq(value);

Iterable<MydDomain> i = repository.findAll(p);
QMyDomain q=QMyDomain.mydomain;
谓词p=q.f1.eq(值);
Iterable i=repository.findAll(p);
要使用REST控制器查询资源,您需要类似以下内容:

@RestController
@RequestMapping(/"mydomain")
public class MyDomainController {

    @Autowired private MyDomainRepository repository;

    @GetMapping("/search/query")
    public List<MyDomain> query(@QuerydslPredicate(root = MyDomain.class) Predicate predicate) {
        return repository.findAll(predicate);
    }
}
@RestController
@请求映射(/“mydomain”)
公共类MyDomainController{
@自动连线私有MyDomainRepository存储库;
@GetMapping(“/search/query”)
公共列表查询(@QuerydslPredicate(root=MyDomain.class)谓词){
返回repository.findAll(谓词);
}
}

这最后一段代码是快速而肮脏的,它可能不会按原样工作(至少返回某种列表),但你明白了。

pvpkiran是对的,没有现成的东西。您需要使用注入式MongoTemplate构建自己的MongoTemplate,例如:

List<MyDomain> findByNameAndValue(string name, string value) {

    Document document = new Document(name, value);
    Query query = new BasicQuery(document.toJson());

    return mongoTemplate.find(query, MyDomain.class);
}
列出findByNameAndValue(字符串名称、字符串值){
文件=新文件(名称、值);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
有趣的是,您可以进一步使用映射传递多个名称/值:

List<MyDomain> findByNamesAndValues(Map<String, String> parameters) {

    Document document = new Document(parameters);
    Query query = new BasicQuery(document.toJson());

    return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(映射参数){
文件=新文件(参数);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
以防万一,这也适用于QueryDSL谓词:

List<MyDomain> findByNamesAndValues(Predicate predicate) {

    AbstractMongodbQuery mongoQuery = new SpringDataMongodbQuery(mongoTemplate, MyDomain.class)
            .where(predicate)
    Query query = new BasicQuery(mongoQuery.toString());

    return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(谓词){
AbstractMongoDB查询mongoQuery=新的SpringDataMongoDB查询(mongoTemplate,MyDomain.class)
.where(谓词)
Query Query=newbasicquery(mongoQuery.toString());
返回mongoTemplate.find(查询,MyDomain.class);
}

这些方法可以进一步改进以处理分页和其他cools功能,如字段包含/排除。

pvpkiran是正确的,没有现成的东西。您需要使用注入式MongoTemplate构建自己的MongoTemplate,例如:

List<MyDomain> findByNameAndValue(string name, string value) {

    Document document = new Document(name, value);
    Query query = new BasicQuery(document.toJson());

    return mongoTemplate.find(query, MyDomain.class);
}
列出findByNameAndValue(字符串名称、字符串值){
文件=新文件(名称、值);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
有趣的是,您可以进一步使用映射传递多个名称/值:

List<MyDomain> findByNamesAndValues(Map<String, String> parameters) {

    Document document = new Document(parameters);
    Query query = new BasicQuery(document.toJson());

    return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(映射参数){
文件=新文件(参数);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
以防万一,这也适用于QueryDSL谓词:

List<MyDomain> findByNamesAndValues(Predicate predicate) {

    AbstractMongodbQuery mongoQuery = new SpringDataMongodbQuery(mongoTemplate, MyDomain.class)
            .where(predicate)
    Query query = new BasicQuery(mongoQuery.toString());

    return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(谓词){
AbstractMongoDB查询mongoQuery=新的SpringDataMongoDB查询(mongoTemplate,MyDomain.class)
.where(谓词)
Query Query=newbasicquery(mongoQuery.toString());
返回mongoTemplate.find(查询,MyDomain.class);
}

这些方法可以进一步改进,以处理分页和其他cools功能,如字段包含/排除。

使用存储库方法是不可能的。为此,您必须使用MongoTemplate。使用存储库方法是不可能的。你必须使用MongoTemplate来解决这个问题我意识到这个答案实际上更像是“初学者的QueryDSL”,而不是你问题的准确答案。我意识到这个答案实际上更像是“初学者的QueryDSL”,而不是你问题的准确答案。谢谢,很好的一点,我正在研究MongoTemplate和QueryDSL,因为当前项目使用MongoRepository,如果可能的话,考虑将MongoTemplate/QueryDSL和MongoRepository结合起来(目前我还不确定)。我有一个项目,在这个项目中,我使用了这两个世界中最好的一个:扩展MongoRepository和QueryDSL PredicateExecutor的存储库(参见我的另一个答案)以及使用mongoTemplate和QueryDsl的自定义服务类。这将为您提供查询数据所需的一切。实际上,不,代码属于向我付款的客户:)它基本上使用了我在两个answe中显示的内容