4

I want to retrieve particular list of element from the Mongodb Table.

Lets suppose i have two variables in my Employee class-:

public Class Employee
{
private String Id;
private String Name;
.
.

now when i will make the fetch query it will be something like -:

List<Employee> list=mongoTemplate.findAll();

and then i will loop through each employee object to fetch the employee ID and save in the List<String>

Now, I want the solution in such a way that i can retrieve all the ID's in one go.Something like-:

List<String> employeeId = someCodeHere; 

Please help if you can

Thanks in advance.

Rishabh Bansal
  • 362
  • 3
  • 7
  • 15

3 Answers3

3

After a year, what you want can be done with the following code:

List<String> employeeIds= mongoTemplate.query(Employee.class).distinct("id").as(String.class).all();

Without the need of making any conversion. I had the same situation and resolved it doing that.

2

According to Mongos Reference documentation on distinct operation:

Finds the distinct values for a specified field across a single collection or view and returns the results in an array.

In Spring Data MongoDB this can be achieved like this:

DistinctIterable<String> distinctIds =
    mongoTemplate.getCollection(mongoTemplate.getCollectionName(Employee.class))
    .distinct("id", String.class);

return Lists.newArrayList(distinctIds);

// or

BasicDBObject dbObject = new BasicDBObject();
dbObject.append("name", new BasicDBObject("$regex", ".*and.*"));

DistinctIterable<String> distinctIds =
    mongoTemplate.getCollection(mongoTemplate.getCollectionName(Employee.class))
    .distinct("id", dbObject, String.class);

return Lists.newArrayList(distinctIds);

MongoTemplate offers here a couple of overloads for distinct. The primer query will collect all IDs for entries of a employee collection directly while the latter one will perform a filtering for only IDs of employees that contain an and within their name.

In order to convert the iterable result set to the requested List of String objects you can make use of Guava's newArray(...) feature.

As @Veeram also mentioned in his comment you can of course also make use of a projected query like

Query query = Query.query(Criteria.where(...));
query.fields().include("id");

return mongoTemplate.find(query, String.class);

where query.fields().include("id") is used to specify the fields you are actually interested in.

In contrast to distinct, this approach will contain duplicate entries in the result list, if there are any. While an ID should in general be unique, performing these two queries on names might produce a result that contains multiple identical entries however.

While the answer given by @Boris is technically valid as well, it might have some performance impact, unfortunately, especially if lots of embedded and referenced documents need to get retrieved as well. I therefore would not recommend such an approach.

Final note: throughout the examples I have kept the Id and Name fields in lower-case letters as this is basically Java naming convention.

Roman Vottner
  • 12,213
  • 5
  • 46
  • 63
0

You can use Java Stream API:

private List<String> getEmployeeIds() {
  return mongoTemplate.findAll().stream()
    .map(Employee::getId)
    .filter(Objects::nonNull)
    .collect(toList());
}

First you query for all employees, then convert to a stream, map Employee to Id and then aggregate all non-null values to a list.

If your Repository uses a Java Stream query method:

Stream<Employee> findAll();

then you don't need to call stream() method inside getEmployeeIds().

EDIT: added filtering a null value from the Stream

Boris
  • 22,667
  • 16
  • 50
  • 71
  • Thanks Boris For your reply – Rishabh Bansal Oct 26 '18 at 07:37
  • can you please tell me how can i make sure that the null values are not added into our list? – Rishabh Bansal Oct 26 '18 at 07:54
  • @RishabhBansal You Can Use This To Remove Null Values From Lists ```list.removeAll(Collections.singleton(null));``` – Farhad Jan 11 '21 at 14:59
  • But When You Are Using Streams This is The Answer ```.filter(Objects::nonNull)``` – Farhad Jan 11 '21 at 15:05
  • 2
    @Boris Is this optimal? I mean is there a way to do this in a database query? – Farhad Jan 11 '21 at 15:07
  • @Farhad perhaps it's not optimal, looking further in [supported keywords for query methods](https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries), `findAllNotNull()` might be the one. Can you check if it works please? – Boris Jan 11 '21 at 16:20
  • @Boris Sure I'll Give it a Try Then I'll Let You Know – Farhad Jan 12 '21 at 17:04