2013-07-05 2 views
1

У меня есть следующие классы:Создание морфий запроса с регулярным выражением

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; 
} 

Но что, если я хочу, чтобы получить запрос для данного только (channelType может быть что угодно) topic? Как мы можем создать запрос для этого?

Одним из вариантов является использование 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

Я думаю, что это может быть тот же вопрос, как http://stackoverflow.com/questions/10901151/mongodb-query-without-field-name. – Trisha

+0

Я ожидаю решения, как описано в [how-to-perform-wildcard-search-in-mongodb-using-java] (http://stackoverflow.com/questions/11552976/how-to-perform-wildcard- search-in-mongodb-using-java). Но я не могу понять, как использовать его для запроса на 'keys'' map' .. (посмотрите в моем примере, 'EnumChannelType' используются в качестве ключа на карте) –

+0

Я хочу сказать, что вы можете сделать это на карте но не по клавишам. Ссылка, которую я опубликовал, указывает, что вы не можете запрашивать ключевые (например, поле) имена в MongoDB. Поэтому я не думаю, что вы можете это сделать. – Trisha

ответ

1

Я почти уверен, что Морфий и 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