我有以下课程:
class Document{
Map<EnumChannelType, Channel> data;
//some more fields
}
class Channel{
String topic;
//some more fields
}
enum EnumChannelType{
BASIC_CHANNEL(1), ADVANCED_CHANNEL(2),......;
int value;
//constructor and some methods
}
现在我想查询topic
内的Channel
。如果channelType
已知,我们可以轻松查询如下:
Query<Document> createQuery(EnumChannelType channelType, String topic){
Query<Document> query = dao.createQuery().disableValidation();
query.field("data." + channelType.name() + ".topic").equal(topic);
return query;
}
但是如果我只想给出topic
(channelType
可以是什么)的查询呢?我们如何为此创建查询?
一个选项是使用or
,如下所示:
Query<Document> createQueryForTopic(String topic) {
Query<Document> query = dao.createQuery().disableValidation();
// add all possible Channel Types
query.or(query.criteria("data." + EnumChannelType.BASIC_CHANNEL.name() + ".topic").equal(topic),
query.criteria("data." + EnumChannelType.ADVANCED_CHANNEL.name() + ".topic").equal(topic),
/*...add criteria for all possible channel types*/);
return query;
}
但如果EnumChannelType
随着时间的推移发生变化或EnumChannelType
拥有大量成员(例如BASIC_CHANNEL(1), ADVANCED_CHANNEL(2),....
),那么这是不可行的。
我正在寻找类似......
的东西Query<Document> createQuery(String topic){
Query<Document> query = dao.createQuery().disableValidation();
// use some regex instead of ????
query.field("data." + ???? + ".topic").equal(topic);
return query;
}
答案 0 :(得分:1)
我几乎可以肯定Morphia和MongoDB不支持字段名称的正则表达式。在这种情况下,最好的选择是使用$or
运算符。您可以遍历整个枚举以避免错误:
List<Criteria> criterias = new ArrayList<Criteria>();
for(EnumChannelType v : EnumChannelType.values()) {
criterias.add(query.criteria("data." + v.name() + ".topic").equal(topic));
}
query.or(criterias.toArray(new Criteria[criterias.size()]);
请记住,$or
运算符并行执行查询,然后合并结果。
信息:http://docs.mongodb.org/manual/reference/operator/or/#op._S_or