如何使用Spring数据从Mongo中的数组文档字段中仅获取匹配结果 [英] How to Get Only Matched Result from An Array Field of Document in Mongo Using Spring Data

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

问题描述

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

我有一个mongo文件酒店,里面有一份评论清单。

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

评论 class有属性 userName

The Review class has property userName.

@Document
public class Hotel {

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

我想通过评论userName搜索所有酒店。

I want to search all the hotel by Review userName.

我的 HotelRepository 公开列表< Hotel> findByReviewsUserName(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构建命名查询,您可以在新创建的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数据从Mongo中的数组文档字段中仅获取匹配结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆