2

I'm trying to get all the values of a specific field to a array.

This is the document structure:

 {

    "title": "testone",
    "docs": [
    {
        "fileId": "123",
        "fileName": "helloworld.txt"
    }, 
    {
        "fileId": "124",
        "fileName": "thisisalongtext.docx",
    }],
 }

Currently I've implemented following

Docs Class :

public class Docs implements Serializable {

    private String fileId;

    public String getFileId() {
        return fileId;
    }

    public void setFileId(String fileId) {
        this.fileId = fileId;
    }
}

Assignment Class:

@Document(collection = "assignemnt")
public class Assignment{

    private String title;
    private List<Docs> docs;

    public String getTitle() {
        return title;
    }


    public List<Docs> getDocs() {
        return docs;
    }

    public void setDocs(List<Docs> docs) {
        this.docs= docs;
    }

    @Override
    public String toString() {
        return "Assignment [title=" + title
            + ", docs=" + docs+ "]";
    }
}

RepositoryImplementation:

public List<Assignment> getAssignments(final String uID) {
    Query query = Query.query(Criteria.where(CREATEDBY).is(uID)
        .orOperator(Criteria.where("docs.0").exists(true),
            (Criteria.where("versionchecked").is(true))));
    return mongoTemplate.find(query, Assignment.class);
}

Current method returns the following response:

 {
            "title": "assignemnt123",
            "docs": [
                {
                    "fileId": "132"
                },
                {
                    "fileId": "123"
                },
                {
                    "fileId": "213"
                }
            ]       
        }

Response I want to create:

   {
                "title": "assignemnt123",
                "docs": [ "132" , "123", "213" ]       
   }

Is there a way to achieve this expected response?

2
  • You need to go with aggregation or you need to do it programmatically... Commented Jul 21, 2021 at 5:06
  • I need it programmatically. I tired with aggregation but it returns in the same format since it's not programmed correctly. Commented Jul 21, 2021 at 5:13

1 Answer 1

1

Create a class that you need the desired output. You have the following classes already

@Data
@AllArgsConstructor
@NoArgsConstructor
class Docs {
  private String fileId;
  private String fileName;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Assignment {
  private String title;
  private List<Docs> docs;
}

Additionally create the following class

@Data
@AllArgsConstructor
@NoArgsConstructor
class ConverterAssignment {
  private String title;
  private List<String> docs;
}

Then you can easily map.

List<Assignment> assignmentList =
        Arrays.asList(
            new Assignment(
                "testone",
                Arrays.asList(
                    new Docs("123", "helloworld1.txt"), new Docs("345", "helloworld2.txt"))),
            new Assignment(
                "testtwo",
                Arrays.asList(
                    new Docs("456", "helloworld3.txt"), new Docs("678", "helloworld4.txt"))));

This is the data you get from repository. With the result, you can use stream() easily. I have tested and worked fine.

List<ConverterAssignment> collect =
        assignmentList.stream()
            .map(
                m ->
                    new ConverterAssignment(
                        m.getTitle(),
                        m.getDocs().stream().map(d -> d.getFileId()).collect(Collectors.toList())))
            .collect(Collectors.toList());

If you want to use aggregations

db.collection.aggregate([
  {
    $project: {
      title: 1,
      docs: "$docs.fileId",
      _id: "$$REMOVE"
    }
  }
])

Working Mongo playground

@Autowired
private MongoTemplate mongoTemplate;

public List<ConverterAssignment> test(String value) {

    Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.project("title").and("docs.fileId").as("docs")
    ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());

    return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(Assignment.class), ConverterAssignment.class).getMappedResults();

}

Note : The java aggregation code is not tested, but it was written based on working mongo playground

Sign up to request clarification or add additional context in comments.

Comments

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.