查找操作后投影嵌入式文档字段

时间:2019-07-08 05:33:59

标签: spring mongodb spring-boot aggregation-framework spring-data-mongodb

我想在时间表之间进行联接:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = TIMESHEET_COLLECTION)
public class Timesheet {

    @Id
    private ObjectId id;
    private ObjectId employeeId;
    private LocalDate date;
    private String occupationTitle;
    private BigDecimal salary;
    private List<TimesheetEntry> entries;
}

和员工(作为嵌入式文档):

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = Employee.EMPLOYEE_COL)
public class Employee {

    @Id
    private ObjectId id;
    private String registry;
    private String cpf;
    private String firstName;
    private String lastName;
    private String nickname;
    private String phone;
    private LocalDate dateOfBirth;
    private LocalDate admissionDate;
    private EmployeeOccupation occupation;
    private EmployeePaymentPreferences paymentPreferences;
    private Map<String, String> equipmentPreferences;
    private Boolean active;
}

所以我有这个 aggregation 查询,具有 match lookup unwind projection < / strong>操作。

Aggregation aggregation = Aggregation.newAggregation(matchTimesheetFilter(timesheetFilter), lookupEmployee(), unwindEmployee(), projectEmployee());

有查找和展开实现。我要放松的原因是员工应该是单个对象,而不是数组。

private LookupOperation lookupEmployee(){
    return LookupOperation.newLookup()
            .from("employee")
            .localField("employeeId")
            .foreignField("_id")
            .as("employee");
}

private UnwindOperation unwindEmployee(){
    return Aggregation.unwind("employee");
}

它成功返回带有嵌入式员工文档时间表文档。关键是:我不想要所有数据。我只想要几个字段

因此,我尝试使用投影操作从员工中排除不需要的字段:

private ProjectionOperation projectEmployee() {
    return Aggregation.project().andExclude("employee.nickname", "employee.firstName", "employee.fullName");
}

它没有用。我的嵌入式员工仍将返回所有字段。但是,如果执行以下操作,则可以成功地从时间表中排除字段:

private ProjectionOperation projectEmployee() {
    return Aggregation.project().andExclude("startDate", "endDate");
}

如何从通过查找操作嵌入的文档中投影自定义字段?

2 个答案:

答案 0 :(得分:0)

我认为您需要排除"employee.nickname", "employee.firstName", "employee.fullName"而不是"nickname", "firstName", "fullName"

尝试一下:

private ProjectionOperation projectEmployee() {
    return Aggregation.project().andExclude("employee.nickname", "employee.firstName", "employee.fullName");
}

答案 1 :(得分:0)

我是这样做的(不确定它是否正确,但是否可行):

private LookupOperation lookupEmployee(){
    return LookupOperation.newLookup()
            .from("employee")
            .localField("employeeId")
            .foreignField("_id")
            .as("employeeLookup");
}

no unwind used

Aggregation.project().and("employeeLookup.firstName").("employee.firstName")