本文介绍了如何使用 Spring Data 从 Mongo 中的文档数组字段中仅获取匹配的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 spring boot 1.5.1MongoDB 3.4.6 版.

我有一个 mongo 文档 Hotel ,其中包含 Review 列表.

I have a mongo document Hotel which has a list of Review .

Review 类具有属性userName.

@Document
public class Hotel {

    @Id
    private String id;
    private List<Review> reviews;

我想通过 Review userName 搜索所有酒店.

I want to search all the hotel by Review userName.

我的 HotelRepositorypublic ListfindByReviewsUserName(String userName);

当我与用户Salman"通话时 -

When I am calling with user 'Salman' -

List<Hotel> list = this.hotelRepository.findByReviewsUserName(user);

此方法返回如下结果:

[
    {
        "id": "59b23c39c70ff63135f76b14",
        "name": "Signature",
        "reviews": [
            {
                "id": 1,
                "userName": "Salman",
                "rating": 8,
                "approved": true
            },
            {
                "id": 2,
                "userName": "Shahrukh",
                "rating": 5,
                "approved": false
            }
        ]
    }
]

我只想要Salman"的评论,但它也为其他人返回.

What I want the reviews only of 'Salman' but it's also returning for others also.

我缺少什么或怎么做?

我注意到,如果单个评论用户匹配它会返回我不想要的评论的整个列表,我想要按名称搜索的评论.

推荐答案

命名查询按原样工作.您并没有明确说您只想要文档的一部分,因此查询返回整个文档.要实现这一点您不能使用命名查询 (请参阅@alexefimov 答案,了解在 @Query 注释的帮助下使用命名查询),但您可以使用 <MongoRepository 旁边的代码>MongoTemplate.为此,您必须进行一些更改:

The named query works as it should be. You are not explicitly saying that you want only a portion of document so query returns whole document. To achieve that you cannot use named queries (see @alexefimov answer for using named queries with help of @Query annotation) but you can use MongoTemplatebeside of MongoRepository. to do that you have to make some changes:

首先你的仓库应该是这样的:

First your repository should be like this:

public interface HotelRepository extends MongoRepository<Hotel, String>, MongoTemplateRepository {
    // You can continue to write your named queries here. Spring will create that.
}

MongoTemplateRepository:

MongoTemplateRepository:

public interface MongoTemplateRepository {
    // You will write your queries which will use mongoTemplate here.
    List<Hotel> findByReviewsUserName(String userName);
}

为了实现 MongoTemplateRepository 方法,您将编写一个新类.重要的是你应该将这个类命名为你的存储库类名+Impl.否则 spring-data 无法找到 MongoTemplateRepository 中定义的方法实现的位置.所以你的实现类的名字应该是 HotelRepositoryImpl

For implementation of MongoTemplateRepository methods, you will write a new class. The important thing here is that you should named this class your repository class name + Impl. Otherwise spring-data cannot find where your methods implementation those defined in MongoTemplateRepository. So your implementation class's name should be HotelRepositoryImpl

public class HotelRepositoryImpl implements MongoTemplateRepository {

    @Autowired
    private MongoTemplate mongoTemplate; // we will use this to query mongoDb

    @Override
    public List<Hotel> findByReviewsUserName(String userName) {
        Query query = new Query();
        query.addCriteria(Criteria.where("reviews.username").is(userName));
        query.fields().include("reviews.$");
        return mongoTemplate.find(query, Hotel.class);
    }
}

用法:

hotelRepository.findByReviewsUserName("userName");

正如您在代码中看到的,我们可以为查询添加 .include().exclude 字段.当您想包含数组字段的匹配部分时,我们使用 $ 运算符和数组字段名称.

As you can see in codes we can .include() or .excludefields for the query. While you want to include just matched part of an array field, we use $operator with array field name.

结论:您仍然可以使用 spring-data 支持良好的命名查询,此外,如果您需要 聚合 或对无法构建命名查询的子文档进行一些复杂查询到春天,您可以在新创建的 mongoTemplate 存储库类中执行此操作.您可以从 HotelRepository 访问所有存储库方法.

Conclusion: You can still use spring-data well supported named queries and additionally if you need aggregation or some complex queries for sub documents that a named query cannot be built by spring, you can do it in your newly created mongoTemplate repository class. And you can access all of your repository methods from HotelRepository.

这篇关于如何使用 Spring Data 从 Mongo 中的文档数组字段中仅获取匹配的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 22:04