将reg表达式数组传递给基于spring的mongo @Query [英] Passing array of reg expressions to spring based mongo @Query

查看:112
本文介绍了将reg表达式数组传递给基于spring的mongo @Query的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在mongodb上使用Spring Boot.我扩展了PagingAndSortingRepository存储库,并添加了以下功能

I'm using Spring boot with mongodb. I've extended PagingAndSortingRepository repository and added the following function

@Query("{'title':{ $nin: [?0]}}")
List<Item> findItem(String[] exclude);

我希望能够向其传递正则表达式数组,例如/dog/,/cat/,/horse/,以排除标题中可能包含其中之一的任何项目.

I want to be able to pass it an array of regular expressions such as /dog/,/cat/,/horse/ to exclude any item that may have one of these in it's title.

上面的功能不起作用,因为将exclude转换为字符串.如何传递正则表达式数组以实现上述目的?

The above function does not work because the exclude is converted to a string. How can I pass an array of regular expressions to be able to do the above?

推荐答案

您可以使用 Querydsl 谓词使用您的一种控制器方法.

You can work it out by using a Querydsl predicate in one of your controller method.

将类似这样的内容添加到您的控制器中:

Add something like this to your controller:

@RequestMapping(value="/search/findByNameRegexNotIn", method = RequestMethod.GET)
@ResponseBody
public List<Item> findByNameRegexNotIn(@RequestParam(name = "name") List<String> names) {
    // build a query predicate
    BooleanBuilder predicate = new BooleanBuilder();  // comes from the Querydsl library
    for (String name : names) {
            predicate.and(QItem.item.name.contains(name).not()); // the QItem class is generated by Querydsl
    }

    List<Item> items = (List<Item>)repository.findAll(predicate);

    return items;
}

您当然可以添加Pageable参数并返回Page< Item>而不是列表.

You can of course add a Pageable parameter and return a Page<Item> instead of a List.


如果您仅将Querydsl用于此目的,则另一个解决方案是覆盖查询参数的默认绑定.


another solution if you use Querydsl for this sole purpose is to override the default bindings of your query parameter.

public interface ItemRepository extends CrudRepository<Item, String>,
    QueryDslPredicateExecutor<Item>, QuerydslBinderCustomizer<QItem> {

    @Override
    default public void customize(QuerydslBindings bindings, QItem item) {
        bindings.bind(item.name).all(
            (path, values) ->  path.matches(StringUtils.collectionToDelimitedString(values, "|")).not());
        // disable query on all parameters but the item name
        bindings.including(item.name);
        bindings.excludeUnlistedProperties(true);
    }
}

控制器方法:

@RequestMapping(value="/search/query", method = RequestMethod.GET)
@ResponseBody
public List<Item> queryItems(
        @QuerydslPredicate(root = Item.class) Predicate predicate) {
        List<Item> items = (List<Item>)repository.findAll(predicate);

        return items;
    }


如果您不想覆盖默认的QuerydslBinderCustomizer#customize,则还可以实现自己的活页夹,并在controller方法中指定它.


if you don't wan't to override the default QuerydslBinderCustomizer#customize, you can also implement your own binder and specify it in the controller method.

public interface ItemRepository extends CrudRepository<Item, String>,
    QueryDslPredicateExecutor<Item> {
    ...
}

控制器方法:

@RequestMapping(value="/search/query", method = RequestMethod.GET)
@ResponseBody
public List<Item> queryItems(
        @QuerydslPredicate(root = Item.class, bindings = ItemBinder.class) Predicate predicate) {
        List<Item> items = (List<Item>)repository.findAll(predicate);

        return items;
    }

活页夹类:

class ItemBinder implements QuerydslBinderCustomizer<QItem> {

@Override
public void customize(QuerydslBindings bindings, QItem item) {
    bindings.bind(item.name).all(
            (path, values) ->  path.matches(StringUtils.collectionToDelimitedString(values, "|")).not()
    );
    bindings.including(item.name);
    bindings.excludeUnlistedProperties(true);
}

}


为了详尽无遗,以及那些不想听到Querysl的人.使用 Spring Data Mongodb参考.


for the sake of exhaustivity and those who don't want to hear about Querysl. Using the solution proposed in Spring Data Mongodb Reference.

定义自定义存储库界面:

Define a custom repository interface:

interface ItemRepositoryCustom {

    public Page<Item> findByNameRegexIn(Collection<String> names, Pageable page);

}

定义自定义存储库实现(需要 Impl 后缀!):

Define an custom repository implementation (Impl postfix required!):

public class ItemRepositoryImpl implements ItemRepositoryCustom {

    @Autowired
    private MongoOperations operations;

    @Override
    public Page<Item> findByNameRegexNotIn(Collection<String> names, Pageable pageable) {
        String pattern = StringUtils.collectionToDelimitedString(names, "|");
        // this time we use org.springframework.data.mongodb.core.query.Query instead of Querydsl predicates
        Query query = Query.query(where("name").regex(pattern).not()).with(pageable);

        List<Item> items = operations.find(query, Item.class);
        Page<Item> page = new PageImpl<>(items, pageable, items.size());

        return page;
    }

}

现在只需扩展ItemRepositoryCustom:

Now simply extend ItemRepositoryCustom:

public interface ItemRepository extends MongoRepository<Item, String>, ItemRepositoryCustom {

...

}

您完成了!

这篇关于将reg表达式数组传递给基于spring的mongo @Query的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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