在Spring Data MongoDB Aggregation中对数组进行分组后,Count操作返回1而不是0

MattIT:

我需要使用具有以下模型的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()原则进行过滤的图书

假设我有四本已出版的书,普通用户又添加了一本,而隐藏的又一本。

  1. 管理员应该知道所有的人,所以他会看到booksCount6
  2. 普通用户只能看到出版或自己添加的,所以他会看到booksCount5
  3. 将来可能还会有其他情况。

我想到了这样的聚合:

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()操作。

  1. 如果books数组大小为0,则始终返回1。
  2. 如果books数组的大小大于0,则返回正确的数量。
  3. 我尝试使用newBuilder(GroupOps.SUM, null, 0)代替count(),但现在总是返回0。
  4. 如果我使用newBuilder(GroupOps.SUM, null, 2)它返回size + 2我不知道怎么回事。

我的问题:

  1. 谁能告诉我我在做什么错以及如何纠正?
  2. 此外,我需要从解析“booksCount” IntegerString小组赛有可能吗?

先感谢您。

当然:

这是因为发生的Aggregation.unwind("books", true);没有连接时,除非您将其设置为,否则该语句将保留为文档Aggregation.unwind("books")默认行为是false然后,当您计数时,该文档将被计为文档。这就是为什么它为您提供1as输出。输出错误的示例

因此,您可以做的是,您可以在下一阶段计算大小。

 project("_id", "published", "title", "books")
   .and(ArrayOperators.Size.lengthOfArray(ConditionalOperators.ifNull("books").then(Collections.emptyList()))).as("booksCount")

工作蒙戈操场正确答案

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章