Search code examples
mongodbgrailsgrails-orm

Grails query using $where with MongoDB


Is there a way to query mongo using the $where directive within Grails/GORM?

I'm trying to run a mongo query much like the following:

db.myAwesomeCollection.find({
    $where : function() { 
        /* Do Something Really Special */
        return true; // or false
    }
});

Solution

  • For the time being, I've added a mongoOperations bean to the resources.xml file:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd        http://www.springframework.org/schema/data/mongo        http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
    <mongo:mongo id="myreplicaset" replica-set="${grails.mongo.replicaSet}">
        <mongo:options
                connections-per-host="300"
                threads-allowed-to-block-for-connection-multiplier="5"
                connect-timeout="10000"
                max-wait-time="120000"
                auto-connect-retry="true"
                socket-keep-alive="false"
                socket-timeout="0"
                slave-ok="false"
                write-number="0"
                write-timeout="0"
                write-fsync="false"/>
    </mongo:mongo>
    
    <mongo:db-factory dbname="${grails.mongo.databaseName}" id="mongoDbFactory" mongo-ref="myreplicaset"/>
    
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongoDbFactory"/>
        <property name="writeResultChecking" value="EXCEPTION"/>
    </bean>
    
    <alias name="mongoTemplate" alias="mongoOperations"/>
    

    Then in my controller, I inject the mongoOperations object:

    def mongoOperations;
    

    I can then call the find() operation on the mongoOperations bean directly.

    String function = "function() { " +
        "return // true if the row matches your criteria" +
        "}";
    
    Query query = new BasicQuery("{\$where : \"" + function + "\"}");
    List<MyDomainClass> results = mongoOperations.find(query, MyDomainClass.class);