我正在使用Spring Boot + MongoDB。我需要根据一些条件来查询数据库,其中我的方法如下所示:
insert into table(a,b,c,d,e,f) values ('Rumania',N'Sighișoara',GETDATE(),0,0,'Test')
我面临的问题是: 在
行search.addCriteria(Criteria.where(“ ItmId”)。in(request.getItmIds()));
request.getItmIds有100万个ID,由于这个原因,我遇到了异常
org.bson.BsonMaximumSizeExceededException:文档大小46282052大于最大值16793600
有人可以帮我吗?
答案 0 :(得分:0)
如果您使用的是MongoTemplate
,则应该能够像这样分页数据:
Query search = new Query()
.with(PageRequest.of(0, 100))
.addCriteria(Criteria.where("ItmId").in(request.getItmIds()));
但是,请注意,MongoTemplate
无法返回Page<MyCollection>
,从而无法为您提供有关总共有多少项的更多信息。
要解决此问题,您必须手动执行计数查询。您可以将其与PageableExecutionutils
结合使用,如this answer所示。
现在您可以分页数据,并且知道元素的总数,那么您应该可以编写一个循环以获取所有数据。
请注意:您仍然在每个查询中发送那100万个ID,MongoDB试图为此类复杂查询找到结果可能会遇到一些困难/性能问题。
或者,在这种情况下,您可以将request.getItmIds()
切成较小的列表,然后分别执行。 Apache Commons Collections 4有一个ListUtils.partition()
方法可以帮助您:
ListUtils
.partition(request.getItmIds(), 100)
.stream()
.map(ids -> Criteria.where("ItmId").in(ids))
.map(criteria -> new Query().addCriteria(criteria))
.map(query -> mongoTemplate.find(query, MyCollection.class))
.flatMap(Collection::stream)
.collect(Collectors.toList());
这会将request.getItmIds()
分成多个列表,每个列表共有100个ID。之后,它将对这些ID执行单独的查询,然后将这些列表连接到一个大列表中。
请注意,但是,无论采用何种方式实现,执行速度都可能很慢。即使您正在执行较小的查询,您仍在尝试获取100万个文档,具体取决于您在何处使用它,可能会遇到其他各种问题,例如:
根据您打算如何使用它,您可能必须提出不同的解决方案,例如:
答案 1 :(得分:-1)
如果您使用的是Spring Data JPA,则可以执行以下操作:
findBySomeField(String someField)
如果您有更复杂的查询,则可以实际使用JPQL并编写自定义查询。
@Query(value = "SELECT o.* from SomeObject o WHERE :someField IS NULL OR o.someField = :somefield)
public findBySomeField(@Param("someField") String someField);