N D Thokare
N D Thokare

Reputation: 1743

Creating morphia query with regex

I have a following classes:

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
}

Now I want to query on topic inside Channel. If channelType is known, we can easily query as below:

Query<Document> createQuery(EnumChannelType channelType, String topic){
    Query<Document> query = dao.createQuery().disableValidation();
    query.field("data." + channelType.name() + ".topic").equal(topic);
    return query;
}

But what if I want to get query for given only topic (channelType can be anything)? How can we create query for this?

One option is using or as follows:

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

But this is not feasible if EnumChannelType is changing over time or if EnumChannelType has large number of members (like BASIC_CHANNEL(1), ADVANCED_CHANNEL(2),....).

I'm looking for something like...

Query<Document> createQuery(String topic){
    Query<Document> query = dao.createQuery().disableValidation();
    // use some regex instead of ????
    query.field("data." + ???? + ".topic").equal(topic);
    return query;
}

Upvotes: 1

Views: 1291

Answers (1)

Miguel Cartagena
Miguel Cartagena

Reputation: 2606

I almost sure that Morphia and MongoDB doesn't support regex on field names. In this case, the best option is use $or operator. You could traverse the whole enum to avoid errors:

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()]);

Remember that $or operator executes queries in parallel and then merge the results.

Info: http://docs.mongodb.org/manual/reference/operator/or/#op._S_or

Upvotes: 1

Related Questions