2

I'm trying to convert the following Mongo query for use with Spring data.

db.product.aggregate([
{$unwind: '$barcodes'},
{$project: {
    _id: 0, 
    productId: '$_id',
    productTitle: '$title',
    productVariation: '$variation', 
    barcode: '$barcodes'
}}])

This is what I've been trying so far. It returns the aggregation, but with null values:

UnwindOperation unwindOperation = Aggregation.unwind("barcodes");

ProjectionOperation projectStage = Aggregation.project().and("productId").as("_id").and("productTitle")
  .as("title")
  .and("productVariation").as("variation")
  .and("barcodeTitle").as("barcodes.title")
  .and("barcodeValue").as("barcodes.value")
  .and("barcodeType").as("barcodes.type")
  .and("codeStandard").as("barcodes.codeStandard")
  .and("quantity").as("barcodes.quantity")
  .and("status").as("barcodes.status");

SortOperation sortOperation = Aggregation.sort(Sort.by(Sort.Direction.DESC, "title"));

Aggregation agg = Aggregation.newAggregation(unwindOperation, projectStage, sortOperation);

AggregationResults<BarcodeAggregateList> results = mongoTemplate.aggregate(agg, "product", BarcodeAggregateList.class);

What it is returning:

return example

The class I am mapping to (has getters/setters):

public class BarcodeAggregateList {
   private String productId;
   private String productTitle;
   private String productVariation;
   private String barcodeTitle;
   private String barcodeValue;
   private String barcodeType;
   private String codeStandard;
   private int quantity;
   private String status;
}

Product class that the data is coming from:

public class Product implements Serializable {
   private static final long serialVersionUID = -998149317494604215L;
   private String id;
   private String title;
   private String description;
   private String SKU;
   private double cost;
   private double retailPrice;
   private String status;
   private LocalDate launchDate;
   private LocalDate discontinueDate;
   private String discontinueReason;
   private String salesChannel;
   private List<Barcode> barcodes;
   private ProductVariation variation;
   private List<Supplier> supplier;
   private Product parentProduct;
   private boolean updateChildren;
   private Label label;
   private int secondaryStockLevel;
   private int primaryStockLevel;
   private Date createdDate;
   private Date modifiedDate;
   private List<Dimension> dimensions;
   private boolean isDeleted = false;
}

Barcode class

public class Barcode {
    private String type;
    private String title;
    private String value;
    private String status;
    private String codeStandard;
    private int quantity;
}

I appreciate any help with this or resources to help me better understand how to perform these types of conversions.

For anyone trying to solve similar issues, I've found the following resources somewhat helpful:

4
  • Is your code working or not ? Commented Oct 22, 2020 at 7:19
  • It is not currently working. It doesn't throw an error, but it only returns null instead of the values. Commented Oct 22, 2020 at 14:29
  • Can you post your product class Commented Oct 23, 2020 at 6:50
  • I updated the post to include the product and barcode class. Commented Oct 23, 2020 at 11:34

1 Answer 1

1

BarcodeAggregateList class fields are null because there is a minor issue in ProjectionOperation's and() and as() methods. The correct syntax is

Aggregation.project().and(SOURCE_FIELD).as(TARGET_FIELD)

You have written and("productId").as("_id") , which is wrong

You need to write this as and("_id").as("productId") , because source field is _id

complete code:

UnwindOperation unwindOperation = Aggregation.unwind("barcodes");

ProjectionOperation projectStage = Aggregation.project()
        .and("_id").as("productId")
        .and("title").as("productTitle")
        .and("variation").as("productVariation")
        .and("barcodes.title").as("barcodeTitle")
        .and("barcodes.value").as("barcodeValue")
        .and("barcodes.type").as("barcodeType")
        .and("barcodes.codeStandard").as("codeStandard")
        .and("barcodes.quantity").as("quantity")
        .and("barcodes.status").as("status");

SortOperation sortOperation = Aggregation.sort(Sort.by(Sort.Direction.DESC, "productTitle"));

Aggregation agg = Aggregation.newAggregation(unwindOperation, projectStage, sortOperation);

AggregationResults<BarcodeAggregateList> results = mongoTemplate.aggregate(agg, "product", BarcodeAggregateList.class);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the help! The changes worked as expected. I just misunderstood the documentation on Spring Data's website and had things reversed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.