Spring中MongoDB正则查询含可为null的phone字段问题
解决方案
问题根源在于MongoDB的$regex操作符不会匹配null值或不存在的字段,所以当你传入".*"作为phone参数时,只会筛选出有phone字段且值符合正则的文档,phone为null或无此字段的文档会被排除。以下是两种调整方案:
方案一:固定包含phone为null的场景
无论传入什么phone参数,查询时都会同时匹配phone符合正则或phone为null(含字段不存在)的文档,适合需要始终包含此类文档的场景:
@Query(value = "{'name': {$regex: ?0, $options: 'i'}, $or: [{'phone': {$regex: ?1, $options: 'i'}}, {'phone': null}]}") Document findByFullNameOrPhone(String fullName, String phone);
方案二:动态匹配(推荐)
仅当phone参数为".*"时,才额外匹配phone为null的文档,其他情况保持原有正则匹配逻辑,更贴合你当前的需求:
@Query(value = "{'name': {$regex: ?0, $options: 'i'}, " + "#{#phone == '.*' ? " + " {$or: [{'phone': {$regex: ?1, $options: 'i'}}, {'phone': null}]}" + " : {'phone': {$regex: ?1, $options: 'i'}}" + "}}") Document findByFullNameOrPhone(String fullName, String phone);
补充说明
- MongoDB中
{'phone': null}默认会匹配两种情况:phone字段值为null,或者文档根本没有phone字段;如果需要严格区分,可以将其替换为{$or: [{'phone': null}, {'phone': {$exists: false}}]},不过多数场景下前者已足够。 - 注意原方法名
findByFullNameOrPhone和原查询的逻辑不符(原查询是AND关系),如果你的实际需求是匹配name符合条件OR phone符合条件,需要将整个查询改为$or包裹name和phone的条件,比如:
@Query(value = "{$or: [{'name': {$regex: ?0, $options: 'i'}}, {'phone': {$regex: ?1, $options: 'i'}}, {'phone': null}]}") Document findByFullNameOrPhone(String fullName, String phone);
内容的提问来源于stack exchange,提问作者TomZ
相关产品推荐
相关产品推荐

