[英]How to return only specific fields for a query in Spring Data MongoDB?
How can we select specific fields in Spring Data Mongo. select Spring Data Mongo 中的特定字段如何获取。 I tried the following but I got cast exception from Foo
to String
.我尝试了以下但我得到了从Foo
到String
的强制转换异常。
Using @Query
使用@Query
@Query(value="{path : ?0}", fields="{path : 0}")
String findPathByPath(String path);
Non @Query
非@Query
String findPathByPath(String path);
Here is the document model这是文档 model
@Document(collection = "foo")
public class Foo {
String name, path;
…
}
MongoDB only returns JSON documents for standard queries. MongoDB 只为标准查询返回 JSON 文档。 What you'd like to see can be achieved by still returning a List<Foo>
.您可以通过仍然返回List<Foo>
来实现。 The fields
property in @Query
will cause only the fields set to 1 being returned. @Query
的fields
属性将导致仅返回设置为 1 的字段。
@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.我们通常建议为此引入一个专用的 DTO,这样您就可以防止将部分填充的Foo
实例依次传递给save(…)
。
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如果 path=Path3,下面的查询将返回 Foo 对象
{
"name": null,
"path": "path3"
}
we need to specify required fields with fieldName:1 and if don't require then specify it with 0.我们需要使用 fieldName:1 指定必填字段,如果不需要,则使用 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.根据我的研究表明,Mongo 没有提供一种方法来从对象中本地返回特定字段的值。 (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). (令人失望,因为能够像在 SQL 或 JSONPath 中那样从字段中返回特定值似乎很基本)。
To get around this, I wrote the following method using Spring MongoDB with Java 11:为了解决这个问题,我使用 Spring MongoDB 和 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. getEmbedded
调用允许我们在返回的 Bson 文档中获取嵌套字段的值。
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.我也不确定这是否比运行 Mongo 聚合查询慢,因为我没有尝试在这两种方法之间运行任何性能比较。
You can directly pass your json query with @Query annotation, for example:您可以使用 @Query 注释直接传递您的 json 查询,例如:
@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这是 Spring 数据 MongoDb 中所有基于 json 的查询的链接 - 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接口,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.您可以使用 getter 方法从 Foo 中获取您感兴趣的字段。
Then in your get request, you would have to specify the projectionName.然后在您的获取请求中,您必须指定 projectionName。 eg with (@Resource path)例如(@Resource 路径)
@RestResource(path = "findByPath", rel = "findByPath")
String findPathByPath(String path);
You could then say (In a get request):然后你可以说(在获取请求中):
..../findByPath?path=target_path&projection=flattenedFoo ..../findByPath?path=target_path&projection=flattenedFoo
this would then return a json with only the fields specifies in FlattenedFoo interface.这将返回一个 json,其中仅包含 FlattenedFoo 接口中指定的字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.