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

jaxagkaj  于 2022-10-04  发布在  Spring
关注(0)|答案(7)|浏览(667)

如何在Spring data Mongo中选择特定的字段。我尝试了以下操作,但得到了从FooString的强制转换异常。

使用@Query

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

@Query

String findPathByPath(String path);

以下是文档模型

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

  String name, path;
  …
}
uqxowvwt

uqxowvwt1#

MongoDB只为标准查询返回JSON文档。您希望看到的结果仍然可以通过返回List<Foo>来实现。@Query中的fields属性将导致仅返回设置为1的字段。

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

我们通常建议为此引入专用DTO,以防止将部分填满的Foo示例轮流交给save(…)

另一种选择是使用聚集框架,但这更加复杂。

j2qf4p5b

j2qf4p5b2#

您可以使用

Query query = new Query();

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

jdgnovmf3#

您可以使用

public interface PersonRepository extends MongoRepository<Person, String>

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

}

有关更多信息,请参阅Spring Data 文档

vfhzx4xs

vfhzx4xs4#

您可以使用下面的查询来获取特定的字段。

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

数据库中存在的记录

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

如果路径=路径3,则下面的查询将返回foo对象

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

我们需要使用fieldName:1指定必填字段,如果不需要,则使用0指定它。

z5btuh9x

z5btuh9x5#

在尝试从集合中的特定对象获取字段的值时,我发现了这个问题。根据我的研究,Mongo没有提供从对象返回特定字段的值的本机方法。(令人失望,因为它似乎非常基本,能够像我在SQL或JSONPath中那样从字段中返回特定值)。

为了解决这个问题,我使用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);
}

getEmbedded调用允许我们获取返回的bson文档中嵌套字段的值。

要使用该方法,只需按如下方式调用它:

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

希望这能帮助其他正在寻找如何做到这一点的人。

顺便说一句,我不确定如何扩展它以返回对象列表--如果我遇到了这个难题并解决了它,我会尝试更新这个答案。我也不确定这是否比运行Mongo聚合查询慢-我还没有尝试对这两种方法进行任何性能比较。

编辑2022-09-30:要返回定制POJO的列表,看起来您必须通过Spring-Data-MongoDB使用聚合查询。此外,基本查询似乎比聚合查询更快,因此在可能的情况下使用基本查询。

n53p2ov0

n53p2ov06#

您可以使用@Query注解直接传递您的json查询,例如:

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

下面是指向Spring data MongoDB-https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongodb.repositories.queries.json-based中所有基于JSON的查询的链接

fkvaft9z

fkvaft9z7#

您可以执行以下操作。

在您的存储库中,您拥有以下方法:

String findPathByPath(String path);

如果文档如下所示(如下所示),并且您只想返回路径

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

  String name;
  String path;
  String type;
  …
}

然后创建一个投影界面,例如

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

您可以使用getter方法从foo获取您感兴趣的字段。

然后,在您的GET请求中,您必须指定项目名称。例如,使用(@资源路径)

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

然后,您可以(在GET请求中)说:

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

然后,这将返回一个只包含在FlattenedFoo接口中指定的字段的json。

相关问题