简体   繁体   English

如何只返回Spring数据MongoDB中查询的特定字段?

[英]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 .我尝试了以下但我得到了从FooString的强制转换异常。

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. @Queryfields属性将导致仅返回设置为 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.

相关问题 如何使用 Java 仅查询 MongoDB 中的特定字段? - How to query only the specific fields in MongoDB with Java? 如何在查询 Java Spring Mongo Repository 中返回特定字段的列表? - How to return list of specific fields in query Java Spring Mongo Repository? 如何在Spring Data MongoDB中保存和查询动态字段? - How to save and query dynamic fields in Spring Data MongoDB? 如何使用查询对象比较 Spring Data MongoDB 中的 2 个字段 - How to compare 2 fields in Spring Data MongoDB using query object 使用 Spring 数据 Rest 和 MongoDB 更新特定字段 - Update Specific Fields with Spring Data Rest and MongoDB MongoDB:如何使用 Java(使用或不使用 Spring)将带有别名的一个查询的特定字段添加到另一个查询的结果? - MongoDB: how to add the specific fields from one query with alias to result of another query using Java (with or without Spring)? 仅返回特定字段 - return only specific fields 如何索引spring数据mongodb中的所有字段? - How to index on all fields in spring data mongodb? 在spring boot中仅从api返回模型的特定字段 - Return only specific fields of model from api in spring boot 如何将 MongoDB 查询转换为 Spring 数据查询 - How to Convert MongoDB Query to Spring Data Query
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM