基于Map Key Spring Repository查询MongoDb

时间:2017-11-22 08:46:00

标签: spring mongodb spring-boot mongodb-query

我需要帮助来查询嵌套文档。将Spring Boot与MongoDB一起使用。

结构:

public class Holiday {
  @Id
  private String id;

  private Integer year;

  private Map<String, List<HolidayElement>>  holidays = new HashMap<>();
}

public class HolidayElement {

  private String name;

  @JsonFormat(pattern="yyyy-MM-dd")
  private Date date;

  private String note;
}

保存Json后的所有内容:

[
   {
      "id": "5a153331b3cb1f0001e1edeb",
      "year": 2017,
      "holidays": {
         "BB": [
            {
                "name": "Neujahrstag",
                "date": "2017-01-01",
                "note": ""
            },
            ...
         ],
         "HH": [
             { ... }
         ]
    }
  ]

现在我怎样才能得到例如:状态为“BB”的“HolidayElement”列表?

1 个答案:

答案 0 :(得分:0)

假设您有像HolidayRepository这样的存储库,则需要创建自定义实现,因为您要使用MongoTemplate。所以你的HolidayRepository看起来像

@Repository
public interface HolidayRepository extends MongoRepository<Holiday, String>, HolidayRepositoryCustom {

} 

并在同一目录中声明两个新文件HolidayRepositoryCustom和HolidayRepositoryImpl(非常重要)作为HolidayRepository

public interface HolidayRepositoryCustom {

  List<HolidayElement> findByMapId(final String mapId);
}

Impl类看起来像这样

public class HolidayRepositoryImpl implements  HolidayRepositoryCustom {


  private final MongoTemplate mongoTemplate;

  @Autowired
  public HolidayRepositoryImpl(final MongoTemplate mongoTemplate) {
    this.mongoTemplate = mongoTemplate;
  }

  @Override
  public List<HolidayElement> findByMapId(String mapId) {

    final QueryBuilder queryBuilder = QueryBuilder.start();
    queryBuilder
        .and("holidays."+mapId).exists(true);

   final DBObject projection = new BasicDBObject();
   projection.put("holidays."+mapId, 1);

    String collectionName = "Holiday";//Change to your collection name
    try( final DBCursor dbCursor = mongoTemplate.getCollection(collectionName).find(queryBuilder.get(), projection)){
      if(dbCursor.hasNext()){
        DBObject next = dbCursor.next();
        Map<String, List<HolidayElement>> holidayElements = 
           (Map<String, List<HolidayElement>>) next.get("holidays");
        return holidayElements.get(mapId);
  }
    }
  return Lists.newArrayList();
  }
}