Java Spring数据REST、QueryDSL和HashMaps—引用HashMap属性时URL中的Null谓词

Java Spring数据REST、QueryDSL和HashMaps—引用HashMap属性时URL中的Null谓词,java,spring,spring-data-mongodb,spring-data-rest,querydsl,Java,Spring,Spring Data Mongodb,Spring Data Rest,Querydsl,我有一个实体对象,我正在使用Spring数据MongoDB在MongoDB中持久化它,并公开一个RESTAPI来查询它。该实体如下所示: Entity.java @Document public class Entity { @Id String id; Map<String, String> properties; } public interface EntityRepository extends MongoRepository&

我有一个实体对象,我正在使用Spring数据MongoDB在MongoDB中持久化它,并公开一个RESTAPI来查询它。该实体如下所示:

Entity.java

 @Document
 public class Entity {
      @Id
      String id;
      Map<String, String> properties;
   }
public interface EntityRepository extends MongoRepository<Entity, String>
                                         ,QueryDslPredicateExecutor<Entity> {
}
@RestController
@RequestMapping(value = "/entities")
public class EntityController {

    private static final Logger logger = LoggerFactory.getLogger(EntityController.class);

    @Autowired
    EntityRepository entityRepository;

    @RequestMapping(method = RequestMethod.GET)
    public Page<Entity> findAllEntities(Pageable pageable) throws ResourceQueryException {
        return entityRepository.findAll(pageable);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/q")
    public Page<Entity> filterEntities(
            @QuerydslPredicate(root = Entity.class) Predicate predicate,
            Pageable pageable) {
        return entityRepository.findAll(predicate,pageable);
    }

}
@文档
公共类实体{
@身份证
字符串id;
地图属性;
}
对应的Spring数据存储库如下所示。它利用了Spring Data MongoDB与QueryDsl的集成:

EntityRepository.java

 @Document
 public class Entity {
      @Id
      String id;
      Map<String, String> properties;
   }
public interface EntityRepository extends MongoRepository<Entity, String>
                                         ,QueryDslPredicateExecutor<Entity> {
}
@RestController
@RequestMapping(value = "/entities")
public class EntityController {

    private static final Logger logger = LoggerFactory.getLogger(EntityController.class);

    @Autowired
    EntityRepository entityRepository;

    @RequestMapping(method = RequestMethod.GET)
    public Page<Entity> findAllEntities(Pageable pageable) throws ResourceQueryException {
        return entityRepository.findAll(pageable);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/q")
    public Page<Entity> filterEntities(
            @QuerydslPredicate(root = Entity.class) Predicate predicate,
            Pageable pageable) {
        return entityRepository.findAll(predicate,pageable);
    }

}
public interface EntityRepository扩展了MongoRepository
,queryDSL谓词执行器{
}
以下是我用来查询存储实体的控制器:

EntityController.java

 @Document
 public class Entity {
      @Id
      String id;
      Map<String, String> properties;
   }
public interface EntityRepository extends MongoRepository<Entity, String>
                                         ,QueryDslPredicateExecutor<Entity> {
}
@RestController
@RequestMapping(value = "/entities")
public class EntityController {

    private static final Logger logger = LoggerFactory.getLogger(EntityController.class);

    @Autowired
    EntityRepository entityRepository;

    @RequestMapping(method = RequestMethod.GET)
    public Page<Entity> findAllEntities(Pageable pageable) throws ResourceQueryException {
        return entityRepository.findAll(pageable);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/q")
    public Page<Entity> filterEntities(
            @QuerydslPredicate(root = Entity.class) Predicate predicate,
            Pageable pageable) {
        return entityRepository.findAll(predicate,pageable);
    }

}
@RestController
@请求映射(value=“/entities”)
公共类实体控制器{
私有静态最终记录器Logger=LoggerFactory.getLogger(EntityController.class);
@自动连线
实体还原性实体还原性;
@RequestMapping(method=RequestMethod.GET)
公共页findAllEntities(可分页可分页)引发ResourceQueryException{
返回entityRepository.findAll(可分页);
}
@RequestMapping(method=RequestMethod.GET,value=“/q”)
公共页面过滤(
@QuerydslPredicate(root=Entity.class)谓词,
可寻呼(可寻呼){
返回entityRepository.findAll(谓词,可分页);
}
}
当我点击url
localhost:8080/entities/q?id=xxx
时,它会按预期工作。但是,当我点击url
localhost:8080/entities/q?properties.p1=v1
(查询
Map
属性的键和值)时,我在方法中得到一个空谓词,因此所有实体都被返回


如何使其正常工作?

您应该将
属性
字段存储为
键值对的
列表
,然后可以在其中进行搜索

您的查询应适用于下一个结构:

{  id : "1233454",
   properties : [ 
        { "key : "key", "value" : "value" }
   ]
}

您应该将
属性
字段存储为
键值
对的
列表
,然后可以在其中进行搜索

您的查询应适用于下一个结构:

{  id : "1233454",
   properties : [ 
        { "key : "key", "value" : "value" }
   ]
}

谢谢你的回答!但是在使用这个模式时,查询具有特定属性的对象变得越来越困难,我不得不求助于$elematch构造。Spring数据网对此的支持似乎严重不足。从URL自动生成谓词对象时,我遇到了一些问题,所以我不得不求助于上面提到的映射方法。但实际上你可以像这里这样编写你的定制绑定:结构应该像我提到的那样,查询像'properties.p1=p2'应该不起作用,或者它在控制台上对你起作用。谢谢你的回答!但是在使用这个模式时,查询具有特定属性的对象变得越来越困难,我不得不求助于$elematch构造。Spring数据网对此的支持似乎严重不足。从URL自动生成谓词对象时,我遇到了一些问题,所以我不得不求助于上面提到的映射方法。但实际上,您可以像这里这样编写自定义绑定:结构应该像我提到的那样,而像“properties.p1=p2”这样的查询不应该工作,或者它可以从控制台为您工作?