gpt4 book ai didi

java - 在 Spring Data MongoDB 聚合中对数组进行分组后,计数操作返回 1 而不是 0

转载 作者:行者123 更新时间:2023-12-04 09:00:04 24 4
gpt4 key购买 nike

我需要使用具有如下模型的 Spring Data MongoDB 创建高级聚合:

@Getter
@Setter
@Document
public class Library {

@Id
@JsonSerialize(using = ToStringSerializer.class)
private ObjectId id;

private Address address;

private String workingHours;

...

}

@Getter
@Setter
@Document
public class Book {

@Id
@JsonSerialize(using = ToStringSerializer.class)
private ObjectId id;

private Boolean published;

private Boolean hidden;

private String title;

@JsonSerialize(using = ToStringSerializer.class)
private ObjectId libraryId;

...

}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.2.0</version>
</dependency>
图书馆馆藏:
{ 
"_id" : ObjectId("5f45440ee89590218e83a697"),
"workingHours" : "8:00 PM - 8:00 AM",
"address" : DBRef("addresses", ObjectId("5f4544198da452a5523e3d11"))
}
藏书:
{ 
"_id" : ObjectId("5f454423be823729015661ed"),
"published": true,
"hidden": false,
"title": "The Hobbit, or There and Back Again"
"libraryId": ObjectId("5f45440ee89590218e83a697")
},
{
"_id" : ObjectId("5f45445b876d08649b88ed5a"),
"published": true,
"hidden": false,
"title": "Harry Potter and the Philosopher's Stone"
"libraryId": ObjectId("5f45440ee89590218e83a697")
},
{
"_id" : ObjectId("5f45446c7e33ca70363f629a"),
"published": true,
"hidden": false,
"title": "Harry Potter and the Cursed Child"
"libraryId": ObjectId("5f45440ee89590218e83a697")
},
{
"_id" : ObjectId("5f45447285f9b3e4cb8739ad"),
"published": true,
"hidden": false,
"title": "Fantastic Beasts and Where to Find Them"
"libraryId": ObjectId("5f45440ee89590218e83a697")
},
{
"_id" : ObjectId("5f45449fc121a20afa4fbb96"),
"published": false,
"hidden": false,
"title": "Universal Parks & Resorts"
"libraryId": ObjectId("5f45440ee89590218e83a697")
},
{
"_id" : ObjectId("5f4544a5f13839bbe89edb23"),
"published": false,
"hidden": true,
"title": "Ministry of Dawn"
"libraryId": ObjectId("5f45440ee89590218e83a697")
}
根据用户的上下文,我必须返回可以根据 startsWith() 过滤的不同数量的书籍。或 like()原则。
假设我有 4 本书已出版,其中一本是普通用户添加的,另一本是隐藏的。
  • 管理员应该知道所有这些,所以他会看到booksCount6 .
  • 普通用户只能看到自己发布或添加的,所以会看到booksCount5 .
  • future 可能还有其他一些条件。

  • 我想出了这样的聚合:
    Criteria criteria = Criteria.where("_id").ne(null).and("address.city").is("Chicago");

    MatchOperation matchOperation = Aggregation.match(criteria);

    LookupOperation lookupOperation = LookupOperation.newLookup().from("books").localField("_id").foreignField("topicId").as("books");

    UnwindOperation unwindOperation = Aggregation.unwind("books", true);

    MatchOperation secondMatchOperation = Aggregation.match(Criteria.where("books.published").is(Boolean.TRUE).orOperator(Criteria.where("creator.userId").is(context.getUserId()));

    AggregationOperation group = Aggregation.group("_id")
    .first("_id").as("id")
    .first("published").as("published")
    .first("title").as("title")
    .push("books").as("books").count().as("booksCount");

    Aggregation aggregation = !isAdministrator() ?
    Aggregation.newAggregation(matchOperation, lookupOperation, unwindOperation, secondMatchOperation, group) :
    Aggregation.newAggregation(matchOperation, lookupOperation, unwindOperation, group);

    mongoTemplate.aggregate(aggregation, "libraries", Document.class).getRawResults().get("results");
    一切正常,而不是 count()手术。
  • 如果books 数组大小为0,它总是返回1。
  • 如果书籍数组大小大于 0,则返回适当的数量。
  • 我试过使用 newBuilder(GroupOps.SUM, null, 0)而不是 count() ,但现在它总是返回 0。
  • 如果我使用 newBuilder(GroupOps.SUM, null, 2)它返回 size + 2 .我不知道发生了什么。

  • 我的问题:
  • 谁能告诉我我做错了什么以及如何纠正它?
  • 另外我需要从 Integer 解析“booksCount”至 String .小组赛可以吗?

  • 先感谢您。

    最佳答案

    这是因为 Aggregation.unwind("books", true); .当没有连接时,除非您将其设为 Aggregation.unwind("books"),否则此语句将保留为文档。 .默认行为是 false .然后当您计数时,该文档被视为一个文档。这就是为什么它给你 1作为输出。 Example with wrong output
    所以你可以做的是,你可以在下一阶段计算大小。

     project("_id", "published", "title", "books")
    .and(ArrayOperators.Size.lengthOfArray(ConditionalOperators.ifNull("books").then(Collections.emptyList()))).as("booksCount")
    工作 Mongo playground with correct answer

    关于java - 在 Spring Data MongoDB 聚合中对数组进行分组后,计数操作返回 1 而不是 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63597076/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com