Realm Java同数组对象嵌套查询:需同时满足子对象双条件
解决Realm嵌套列表的同子项多条件查询问题
你遇到的是Realm查询嵌套RealmList时的典型逻辑陷阱:默认情况下,针对嵌套列表的多个条件是跨不同子对象匹配的(比如只要有一个子对象满足email条件,另一个子对象满足type条件,这条父记录就会被选中),但你需要的是存在同一个子对象同时满足两个条件的父记录。
正确的解决方案
针对Realm 5.8.0版本,有两种清晰的实现方式:
方式1:使用exists()子查询(推荐,代码可读性更高)
先构建子查询筛选出符合条件的子对象,再查询父对象中存在该子对象的记录:
// 先创建子查询,找到同时满足email和type条件的ChecklistParticipants RealmQuery<ChecklistParticipants> subQuery = mRealm.where(ChecklistParticipants.class) .contains("email", "a@a.com", Case.INSENSITIVE) .equalTo("type", 0); // 查询存在符合子查询条件的checklistParticipants的AdditionalData记录 RealmResults<AdditionalData> results = mRealm.where(AdditionalData.class) .exists("checklistParticipants", subQuery) .findAll();
方式2:使用Realm查询语言(RQL)直接过滤
通过ANY关键字指定“存在至少一个子对象满足所有后续条件”,结合大小写不敏感的匹配语法:
RealmResults<AdditionalData> results = mRealm.where(AdditionalData.class) .filter("ANY checklistParticipants.email CONTAINS[c] 'a@a.com' AND checklistParticipants.type = 0") .findAll();
这里的CONTAINS[c]对应你之前用的Case.INSENSITIVE,表示大小写不敏感的包含匹配。
为什么你之前的写法不生效?
- 第一种链式查询:先查满足email的父记录,再在结果中查满足type的,本质还是跨子项的“与”逻辑——只要父记录里有一个子对象满足email,且有任意一个子对象(可以是另一个)满足type,就会被选中,不符合你要的“同一个子对象同时满足”的要求。
- 第二种直接链式
.and()的写法:Realm默认对嵌套列表的多条件是“存在子对象满足email 并且 存在子对象满足type”,但这两个子对象可以是不同的,所以依然会匹配到你截图里的那条记录(一个子对象满足email,另一个满足type)。
额外注意点
你给出的ChecklistParticipants实体类中,type字段定义为String类型,但代码里用的是equalTo("type", 0)(传入int值)。如果数据库中type实际存储的是数字类型(比如0、1),建议把实体类的type字段改成int类型,避免类型转换导致的查询异常:
class ChecklistParticipants{ String email; int type; // 修正为int类型,对应代码中的数字条件 String field3; }
内容的提问来源于stack exchange,提问作者Aks4125
相关产品推荐
相关产品推荐

