Michael
Michael

Reputation: 13636

How to return list of specific fields in query Java Spring Mongo Repository?

I use Java spring and MongoDB repository in my project.

Here is DTO definition:

@Document(collection = "Info")
public class Info  {

  String id,
  Integer count,
  String type
  …
}

I need to return from the query a list of IDs where the count field not zero and type filed has 'binary' text.

Here how I try to implement it:

@Query(value="{ 'count' : 0, 'type' : 'binary' }", fields="{ 'id' : 1 }")
List<String> getInfo();

I get this result from query above:

0={"_id": {"$oid": "5eb97a8139d4c62be4d90e4c"}}
1={"_id": {"$oid": "3ec97a8127d4c60cb4d90e9e"}}

And I expect this result:

{"5eb97a8139d4c62be4d90e4c", "3ec97a8127d4c60cb4d90e9e"}

So as you can see I expect to get a list of id strings from the query above.

Any idea what should I change in the query above to get the expected list of ids results?

Upvotes: 4

Views: 6507

Answers (5)

Dmitriy Chernykh
Dmitriy Chernykh

Reputation: 1

It is possible:

@Aggregation(pipeline = {"{$match: {}} " +
        "{$project: { _id: { $toString: $_id } }} " +
        "{$group: {_id: null, ids: { $push: $_id }}} " +
        "{$project: { _id: 1 }}"})
List<String> getInfo();

Upvotes: 0

I have 2 suggestions.

1. You can use JPA query instead of named query

    public interface InfoRepository extends MongoRepository<Info, String> {
         List<Info> findByCountAndType(final Integer count, final String type);
    }

2. Use java stream api in your business logic to collect all id as List from the above result.

    public class InfoServiceImpl {
       @Autowired
       private InfoRepository repository;

       public String getIds(final String type, final Integer count) {
           return repository.findByCountAndType(count, type)
                  .stream()
                  .map(Info::getId)
                  .collect(Collectors.toList());
       }

Upvotes: 0

Dĵ ΝιΓΞΗΛψΚ
Dĵ ΝιΓΞΗΛψΚ

Reputation: 5689

the best you can get back is a document with an array field with the found ids like this:

{
    "ids" : [
        "606018909fb6351e4c34f964",
        "606018909fb6351e4c34f965"
    ]
}

which can be achieved with an aggregation query like so:

db.Info.aggregate([
    {
        $match: {
            count: 0,
            type: "binary"
        }
    },
    {
        $project: { _id: { $toString: "$_id" } }
    },
    {
        $group: {
            _id: null,
            ids: { $push: "$_id" }
        }
    },
    {
        $project: { _id: 0 }
    }
])

Upvotes: 0

Anish B.
Anish B.

Reputation: 16549

No, that's impossible what you are thinking.

Reason : MongoDB can only return JSON Document. You can include the fields that you want to be there.

This suggestion that you can follow :

DTO Definition :

@Document(collection = "Info")
public class Info  {

  @Id
  private String id;
  
  private Integer count;
  
  private String type;
  
  // other fields and getters and setters
}

Sample Repository :

public interface InfoRepository extends MongoRepository<Info, String> {

   @Query(value="{ 'count' : 0, 'type' : 'binary' }", fields="{ 'id' : 1 }")
   List<Info> getInfo();
 
}

Sample Service class :

@Service
public class InfoService {

   @Autowired 
   private InfoRepository infoRepository;

   public List<String> getIds() {
   
      return infoRepository.getInfo()
                      .stream()
                      .map(Info::getId)
                      .collect(Collectors.toList());    

   }

}

 

Upvotes: 3

Joe
Joe

Reputation: 28366

The returned {"$oid": "5eb97a8139d4c62be4d90e4c"} is the MongoDB Extended JSON representation of an ObjectID.

It is not returning a string because the field stored in the database is of type ObjectID, not type String.

If you want it to return a string, you should use aggregation with the $toString operator to convert it.

Upvotes: 0

Related Questions