简体   繁体   中英

How to return only specific fields for a query in Spring Data MongoDB?

How can we select specific fields in Spring Data Mongo. I tried the following but I got cast exception from Foo to String .

Using @Query

@Query(value="{path : ?0}", fields="{path : 0}")
String findPathByPath(String path);

Non @Query

String findPathByPath(String path);

Here is the document model

@Document(collection = "foo")
public class Foo  {

  String name, path;
  …
}

MongoDB only returns JSON documents for standard queries. What you'd like to see can be achieved by still returning a List<Foo> . The fields property in @Query will cause only the fields set to 1 being returned.

@Query(value="{ path : ?0}", fields="{ path : 0 }")
List<Foo> findByPath(String path);

We usually recommend introducing a dedicted DTO for that so that you prevent the partially filled Foo instance from being handed to save(…) in turn.

Another option is using the aggreation framework but that's more involved.

You can use

Query query = new Query();

query.fields().include("path");

You can use

public interface PersonRepository extends MongoRepository<Person, String>

  @Query(value="{ 'firstname' : ?0 }",fields="{ 'firstname' : 1, 'lastname' : 1}")
  List<Person> findByThePersonsFirstname(String firstname);

}

More information in spring data documentation

You can use below query to get specific fields.

@Query(fields="{path : 1}")
Foo findPathByPath(String path);

Records present in DB

{
    "name" : "name2",
    "path" : "path2"
},
{
    "name" : "name3",
    "path" : "path3"
}

Below query will return Foo object if path=Path3

{
    "name": null,
    "path": "path3"
}

we need to specify required fields with fieldName:1 and if don't require then specify it with 0.

I found this question while trying to get the value of a field from a specific object in my collection. From what my research shows, Mongo doesn't provide a way to natively return just a specific field's value from an object. (Disappointing since it seems pretty basic to be able to return just a specific value from a field like I would do in SQL or JSONPath).

To get around this, I wrote the following method using Spring MongoDB with Java 11:

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.MongoTemplate; //not used, just showing which type the template is
import java.util.Arrays;
import static java.util.Objects.requireNonNull;

/**
 * Use this method to get a specific field from an object saved in Mongo. The objectId will be
 * the id of the object to fetch, and the fieldValueToReturn will be the field to return.
 *
 * @return the value of the provided field-path converted to the class type provided
 */
public <T> T getFieldValueById(String objectId, String fieldValueToReturn, String collectionName, Class<T> classTypeToReturn) {
    var query = new Query().addCriteria(Criteria.where("_id").is(objectId));
    query.fields().include(fieldValueToReturn);
    var result = mongoTemplate.findOne(query, org.bson.Document.class, collectionName);
    requireNonNull(result, "Did not find any documents with id '" + objectId + "' in collection: " + collectionName);
    return result.getEmbedded(Arrays.asList(fieldValueToReturn.split("\\.")), classTypeToReturn);
}

The getEmbedded call allows us to get the value of the nested field within the returned Bson document.

To use the method, just call it like this:

getFieldValueById("A1234", "field.nestedfield.nestedfield", "collectionName", String.class);

Hopefully this helps out someone else looking on how to do this.


As a side note, I'm not sure how to extend this to return a list of objects - if I get to that dilemma and solve it, I will try to update this answer. I'm also not sure if this is slower than running a Mongo aggregate query, by I haven't tried running any performance comparisons between the two methods.

You can directly pass your json query with @Query annotation, for example:

@Query("{ 'firstname' : 'john' }")

Here is the link to all json based queries in Spring Data MongoDb - https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries.json-based

You can do the following.

In your repository, you have the method:

String findPathByPath(String path);

If the document looks like this (below), and you want to only return path

@Document(collection = "foo")
public class Foo  {

  String name;
  String path;
  String type;
  …
}

Then create a Projection interface, eg

@Projection(name = "flattenedFoo", types = Foo.class)
public interface FlattenedInvoice {
    String getPath(); // This returns the path value in Foo class
}

You can use the getter methods to get the fields from Foo that you are interested in.

Then in your get request, you would have to specify the projectionName. eg with (@Resource path)

@RestResource(path = "findByPath", rel = "findByPath")
String findPathByPath(String path);

You could then say (In a get request):

..../findByPath?path=target_path&projection=flattenedFoo

this would then return a json with only the fields specifies in FlattenedFoo interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM