Complex Query

292 views
Skip to first unread message

Jose da Silva

unread,
Sep 7, 2010, 9:20:57 PM9/7/10
to mongodb-user
Hello,

Input:

$ipum = 'someipnum';


My document schema

"country", "ipstart","ipend","ipnum_start","ipnum_end"

I am trying to do the following query.

get all documents where document.ipnum_start >= $ipnum AND
document.ipnum_end <= $ipnum

I was able to get the desirable result using $where although it is too
slow.

'$where' => 'function() {
return (this.start_num<='.$ipnum.' && this.end_num>='.
$ipnum.');
}'

Anyone know how can i do this by using a query that uses indexes?
Contrarly on what does $where ?

roger

unread,
Sep 7, 2010, 10:57:14 PM9/7/10
to mongodb-user

Could you store the result of the comparision, i.e. store the result
of document.ipnum_start >= $ipnum AND
document.ipnum_end <= $ipnum in another field in the document as a
boolean ?

-Roger

Kristina Chodorow

unread,
Sep 7, 2010, 11:01:10 PM9/7/10
to mongod...@googlegroups.com
You can just use $gte and $lte, if I understand correctly:

$collection->find(array('ipnum_start' => array('$gte' => $ipnum), 'ipnum_end' => array('$lte' => $ipnum)));
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.


Jose da Silva

unread,
Sep 8, 2010, 5:55:45 AM9/8/10
to mongodb-user
Hi Cristina

That was the obvious situation, and the first one i tried, for some
reason it doesn't work.

The suggest query performs and AND or an OR ?

$collection->find(array('ipnum_start' => array('$gte' => $ipnum),
> 'ipnum_end' => array('$lte' => $ipnum)));

Meaning, is this : ipnum_start>=$ipnum AND ipnum_end<=$ipnum or its
is ipnum_start>=$ipnum OR ipnum_end<=$ipnum ?
> > mongodb-user...@googlegroups.com<mongodb-user%2Bunsu...@googlegroups.com>
> > .

Jose da Silva

unread,
Sep 8, 2010, 5:56:07 AM9/8/10
to mongodb-user
Hi

That is not an option, $ipnum is a dynamic value.

Kristina Chodorow

unread,
Sep 8, 2010, 9:09:42 AM9/8/10
to mongod...@googlegroups.com
Multiple conditions perform an AND.  Do you mean $ipnum is dependent on other fields in the document?  It's fine if it's a variable.


--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.

Joseph Wang

unread,
Sep 8, 2010, 11:34:43 PM9/8/10
to mongod...@googlegroups.com
I've multiple threads running, each is fetching data from different table.
In each thread, I first get Mongo from a singleton. It then loops thru
document and convert them to TableRow object and then to a ArrayList<Object>.
[See code for one of the thread.]

1. The time for a thread to run collection.find(dbQuery) seems inconsistent.
Have seen 5ms to 160ms (for the same query). Running mongo on 68G EC2
instance. Index size + storage size is around 32G. All the query fields are
indexed. Any suggestion how I can troubleshoot this. Want to get the query
time down  >10ms.
2. Any suggestion on fastest way to  convert DBObject to Java Object?
Does Morphia or other POJO mapper have lower overhead than
calling BasicDBObject.getString() and BasicDBObject.getDouble()?


            Mongo mongo = MongoConnnection.getInstance().getMongo();
            ArrayList<Tuple> tuples = new ArrayList<Tuple>();
            long fStart = System.currentTimeMillis();
            DB db = mongo.getDB(dbName);
            if (db != null) {
                DBCollection coll = db.getCollection(collectionName);
                DBCursor cur = null;

                cur = coll.find(dbQuery);
                while (cur.hasNext()) {
                    BasicDBObject dbo = (BasicDBObject) cur.next();
                    TableRow row = new TableRow(dbo);
              
                    tuples.add(row.getTuple());
                    long time = (timeout - (System.currentTimeMillis() - fStart));
                    if (time < 0) {
                        break;
                    }
                }

Scott Hernandez

unread,
Sep 8, 2010, 11:53:41 PM9/8/10
to mongod...@googlegroups.com
On Wed, Sep 8, 2010 at 8:34 PM, Joseph Wang <joseph...@yahoo.com> wrote:
I've multiple threads running, each is fetching data from different table.
In each thread, I first get Mongo from a singleton. It then loops thru
document and convert them to TableRow object and then to a ArrayList<Object>.
[See code for one of the thread.]

1. The time for a thread to run collection.find(dbQuery) seems inconsistent.
Have seen 5ms to 160ms (for the same query). Running mongo on 68G EC2
instance. Index size + storage size is around 32G. All the query fields are
indexed. Any suggestion how I can troubleshoot this. Want to get the query
time down  >10ms.

Are you doing any updates/saves at the same time? Can you run mongostat for a bit and post that.

What does "free -ltm" look like after you reach a steady state?

2. Any suggestion on fastest way to  convert DBObject to Java Object?
Does Morphia or other POJO mapper have lower overhead than
calling BasicDBObject.getString() and BasicDBObject.getDouble()?

Morphia just wraps the DBObject and won't perform any faster than the driver will. It has very little overhead though and could let you write, and test, less of your own code. It is hard to know how it might compare without see the constructor for TableRow ("TableRow row = new TableRow(dbo);")
 
            Mongo mongo = MongoConnnection.getInstance().getMongo();
            ArrayList<Tuple> tuples = new ArrayList<Tuple>();
            long fStart = System.currentTimeMillis();
            DB db = mongo.getDB(dbName);
            if (db != null) {
                DBCollection coll = db.getCollection(collectionName);
                DBCursor cur = null;

                cur = coll.find(dbQuery);
                while (cur.hasNext()) {
                    BasicDBObject dbo = (BasicDBObject) cur.next();
                    TableRow row = new TableRow(dbo);
              
                    tuples.add(row.getTuple());
                    long time = (timeout - (System.currentTimeMillis() - fStart));
                    if (time < 0) {
                        break;
                    }
                }

It is also possible that you could optimize the batch sizes used for your queries (cursor), depending on how large your documents are, and how many you expect (less network round-trips are better). 

Joseph Wang

unread,
Sep 9, 2010, 12:54:50 AM9/9/10
to mongod...@googlegroups.com

If I've 155 documents in the result set, do I simply do
       DBCursor cur = coll.find(dbQuery).batchSize(100);

       while (cur.hasNext()) {
           ...
        }
limit 100 documents per batch? The driver will automatically fetch first 100 documents,
then 55 documents when cur.hasNext() is called? Nice feature to have.

Constructor for TableRow(BasicDBObject) simply calls various BasicDBObject.get
methods:
   public TableRow(BasicDBObject obj) {       
        st = obj.getString("st");
        points = obj.getString("pt");
        productId = obj.getInt("prod", 0);
        ...
        productType = obj.getString("prodtype");
    }

[root@ip-10-166-57-74 bin]# ./mongostat -h localhost:10000 5
connected to: localhost:10000
insert/s query/s update/s delete/s getmore/s command/s flushes/s mapped  vsize    res faults/s locked % idx miss %    q t|r|w  conn       time
       0       0        0        0         0         0         0 105342 105701  52381        0        0          0      0|0|0    13   00:43:37
       0       0        0        0         0         0         0 105342 105701  52381        0        0          0      0|0|0    13   00:43:42
       0       0        0        0         0         0         0 105342 105701  52381        0        0          0      0|0|0    13   00:43:47
       0       0        0        0         0         0         0 105342 105701  52381        0        0          0      0|0|0    13   00:43:52
       0       0        0        0         0         0         0 105342 105701  52381        0        0          0      0|0|0    13   00:43:57




From: Scott Hernandez <scotthe...@gmail.com>
To: mongod...@googlegroups.com
Sent: Wed, September 8, 2010 8:53:41 PM
Subject: Re: [mongodb-user] Suggestion on speeding up data fetch and conversion
--

Eliot Horowitz

unread,
Sep 9, 2010, 12:57:10 AM9/9/10
to mongod...@googlegroups.com
You should turn on the db profiler and set the threshold to 20ms.
Then can see if there are slow db operations, which ones.
Will also tell you if its the db or something else.

Joseph Wang

unread,
Sep 9, 2010, 12:57:59 AM9/9/10
to mongod...@googlegroups.com
What is the default batchSize? Does DBCursor fetch one
document at a time if batchSize(n) is not used?

Thanks in advance.


From: Joseph Wang <joseph...@yahoo.com>
To: mongod...@googlegroups.com
Sent: Wed, September 8, 2010 9:54:50 PM

Eliot Horowitz

unread,
Sep 9, 2010, 12:59:15 AM9/9/10
to mongod...@googlegroups.com
No - it'll fill a 4mb buffer at the server and send that

Joseph Wang

unread,
Sep 9, 2010, 9:54:02 AM9/9/10
to mongod...@googlegroups.com
The performance seems slow for the first few queries from the webserver
after webserver was restarted. The first query took 250ms. The second
query took 100ms. The third query took 38ms. All subsequent queries
seem to take <10ms. Already tried to connect to mongo server during init
context event. Doesn't seem to help with the high query time for
the first few queries.


----- Original Message ----
From: Eliot Horowitz <elioth...@gmail.com>
To: mongod...@googlegroups.com
Sent: Wed, September 8, 2010 9:57:10 PM
Subject: Re: [mongodb-user] Suggestion on speeding up data fetch and conversion

Kristina Chodorow

unread,
Sep 9, 2010, 10:05:50 AM9/9/10
to mongod...@googlegroups.com
That's probably just the database loading data into memory the first time you access it.  It starts out with all of the data on disk, and then puts the stuff you access into memory so it'll be faster for subsequent queries.

Joseph Wang

unread,
Sep 9, 2010, 10:13:49 AM9/9/10
to mongod...@googlegroups.com
Don't think that is the case here. Only restarted webserver. Saw query time
> 100ms even if I restarted webserver w/i few minutes.



From: Kristina Chodorow <kris...@10gen.com>
To: mongod...@googlegroups.com
Sent: Thu, September 9, 2010 7:05:50 AM

Scott Hernandez

unread,
Sep 9, 2010, 11:24:30 AM9/9/10
to mongod...@googlegroups.com
When did it change from a default number of items to filling a 4MB packet?

Kristina Chodorow

unread,
Sep 9, 2010, 11:32:15 AM9/9/10
to mongod...@googlegroups.com
If you don't send a batch size, the first db response contains min(100 docs, 4MB).  Subsequent requests return 4MB (although they can actually return up to 16MB if you've got large documents).  AFAIK, it's always been this way.

Michael Dirolf

unread,
Sep 9, 2010, 11:27:11 AM9/9/10
to mongod...@googlegroups.com
This hasn't changed - a query response uses a default of min(100,
4mb-worth). getmore uses a default of 4mb-worth.

Joseph Wang

unread,
Sep 11, 2010, 3:29:40 PM9/11/10
to mongod...@googlegroups.com
Are field names case sensitive? For example, does Mongo treat
"lM" and "lm" as the same field name?

Joshua Kehn

unread,
Sep 11, 2010, 3:33:22 PM9/11/10
to mongod...@googlegroups.com
Yes it appears to be.

p = {}
d = {}
p.id = 1
d.id = 1
db.casetest.insert(p)
db.casetest.insert(d)
db.casetest.find({id:1}) // Yields one result.

Regards,

-Josh
____________________________________
Joshua Kehn | Josh...@gmail.com

On Sep 11, 2010, at 3:29 PM, Joseph Wang wrote:

Are field names case sensitive? For example, does Mongo treat
"lM" and "lm" as the same field name?


Scott Hernandez

unread,
Sep 11, 2010, 3:35:49 PM9/11/10
to mongod...@googlegroups.com
It is case sensitive, see.

> db.test.save({lm:1, LM:1, Lm:1})
> db.test.findOne()
{
        "_id" : ObjectId("4c8bd995837f00000000136c"),
        "lm" : 1,
        "LM" : 2,
        "Lm" : 3
}

On Sat, Sep 11, 2010 at 12:29 PM, Joseph Wang <joseph...@yahoo.com> wrote:
Are field names case sensitive? For example, does Mongo treat
"lM" and "lm" as the same field name?

Scott Hernandez

unread,
Sep 11, 2010, 3:38:57 PM9/11/10
to mongod...@googlegroups.com
Josh, I'm not sure what you are talking about.

> db.test.insert({id:1})
> db.test.insert({id:1})
> db.test.find()
{ "_id" : ObjectId("4c8bda57837f00000000136d"), "id" : 1 }
{ "_id" : ObjectId("4c8bda58837f00000000136e"), "id" : 1 }
> db.test.find({id:1})
{ "_id" : ObjectId("4c8bda57837f00000000136d"), "id" : 1 }
{ "_id" : ObjectId("4c8bda58837f00000000136e"), "id" : 1 }

Joshua Kehn

unread,
Sep 11, 2010, 3:40:46 PM9/11/10
to mongod...@googlegroups.com
Scott-

Ah, seems I didn't capitalize ID for `d` like I did when I plugged it into the shell.

Should be:

p.id = 1
d.ID = 1

Thanks,

-Josh
____________________________________
Joshua Kehn | Josh...@gmail.com

Joseph Wang

unread,
Sep 11, 2010, 6:39:46 PM9/11/10
to mongod...@googlegroups.com
I've some collections that rarely get updated/modified. Is there a way to change
default padding factor s.t. the overall space associated with those collections
are smaller?



roger

unread,
Sep 11, 2010, 7:16:33 PM9/11/10
to mongodb-user
Hi, you can't manually overide the padding factor. The padding factor
is
calculated by the database using an adaptive algorithm.

-Roger

Joseph Wang

unread,
Sep 11, 2010, 9:12:13 PM9/11/10
to mongod...@googlegroups.com
Have a master-slave setup on 68G EC2. Run 300 concurrent queries.
Using Java driver 2.1. Both master and slave have maxConns 500.

root 14757 29.3 33.7 36246288 24171516 ? Sl 17:18 66:01
/root/mongodb-linux-x86_64-1.6.2/bin/mongod --dbpath /mnt/data/lp --slave
--source ip-10-166-57-74:10000 --port 10000 --fork --logpath /mnt/data/logs/db
--maxConns 500 --oplogSize 50000 --autoresync


See
com.mongodb.DBPortPool$SemaphoresOut: Out of semaphores to get db connection

in webserver log.



Joseph Wang

unread,
Sep 11, 2010, 9:21:28 PM9/11/10
to mongod...@googlegroups.com
Never mind. Found the previous blog.

http://groups.google.com/group/mongodb-user/browse_thread/thread/c699b5fde98eafe9

Set opt.connectionsPerHost=1000. Will rerun load test.


----- Original Message ----
From: Joseph Wang <joseph...@yahoo.com>
To: mongod...@googlegroups.com

in webserver log.


Joseph Wang

unread,
Sep 18, 2010, 2:37:57 AM9/18/10
to mongod...@googlegroups.com

Kristina Chodorow

unread,
Sep 18, 2010, 8:13:31 AM9/18/10
to mongod...@googlegroups.com
Fixed, thanks!

Joseph Wang

unread,
Sep 18, 2010, 11:18:58 AM9/18/10
to mongod...@googlegroups.com
Started mongo with --profile=1 on both master and slave. Run a 10 mins load
test.

Didn't see any information related to my collection. I used
http://www.mongodb.org/display/DOCS/Database+Profiler
to setup profiler. Anything else that I need to do? How do I set it to profile
queries
that are slower than 10ms?

[root@ip-10-166-59-166 ~]# mongodb-linux-x86_64-1.6.2/bin/mongo localhost:10000
MongoDB shell version: 1.6.2
connecting to: localhost:10000/test
> db.getProfilingLevel()
0
> db.setProfilingLevel(2);
{ "was" : 0, "slowms" : 100, "ok" : 1 }
> db.getProfilingLevel()
2
> db.system.profile.find( { millis : { $gt : 0}})
> db.system.profile.find()
{ "ts" : "Sat Sep 18 2010 10:58:00 GMT-0400 (EDT)", "info" : "query test.$cmd
ntoreturn:1 command: { profile: -1.0 } reslen:74 bytes:58", "millis" : 0 }
{ "ts" : "Sat Sep 18 2010 11:13:30 GMT-0400 (EDT)", "info" : "query
test.system.profile reslen:36 nscanned:1 \nquery: { millis: { $gt: 0.0 } }
nreturned:0 bytes:20", "millis" : 0 }

----- Original Message ----
From: Eliot Horowitz <elioth...@gmail.com>
To: mongod...@googlegroups.com
Sent: Wed, September 8, 2010 9:57:10 PM
Subject: Re: [mongodb-user] Suggestion on speeding up data fetch and conversion

Joseph Wang

unread,
Sep 19, 2010, 12:52:03 AM9/19/10
to mongod...@googlegroups.com
I've following code in webapp that fetches data from a master-slave setup.

1) Is it safe to store mongo.getDB() object across multiple threads?
2) For read query, do we still need to call db.requestStart() and
db.requestDone().
3) For the same query, timing for
while (cur.hasNext())
loop varies from 800ms to 20ms. Tried running profiling option on mongo
server. Didn't see anything related to the collection.
a) If mongo auto packs result up to 4M, is there a danger in specifying
batchSize() that may return results that is greater than 4M?
b) What is the difference between calling DBCursor.size() and
DBCuror.count()?
c) Is there a safe way to turn each chunk of results into an array?
Something like
List<DBObject> results = new List<DBObject>();
while (cur.hasNext()) {
List<DBObject> list = cur.toArray();
results.addAll(list);
}
d) Any explanation why the performance varies so much for the same query?


Code fragment:
ArrayList<Tuple> tuples = new ArrayList<Tuple>(200);


DB db = mongo.getDB(dbName);
if (db != null) {

db.requestStart();

DBCollection coll = db.getCollection(collectionName);
DBCursor cur = null;

cur = coll.find(dbQuery).addOption(Bytes.QUERYOPTION_SLAVEOK);
while (cur.hasNext()) {
BasicDBObjectdbo = (BasicDBObject) cur.next();
BaseTableRow row = new BaseTableRow(dbo);
tuples.add(row.getTuple());
}
db.requestDone();
}


Eliot Horowitz

unread,
Sep 19, 2010, 9:27:18 AM9/19/10
to mongod...@googlegroups.com
> 1) Is it safe to store mongo.getDB() object across multiple threads?

Yes.

> 2) For read query, do we still  need to call db.requestStart() and
> db.requestDone().

No - you only need to use those if you are doing writes then reads and
need the reads to know about the writes.

> 3) For the same query, timing for
>         while (cur.hasNext())
>    loop varies from 800ms to 20ms. Tried running profiling option on mongo
>    server. Didn't see anything related to the collection.
>    a) If mongo auto packs result up to 4M, is there a danger in specifying
>        batchSize() that may return results that is greater than 4M?

No - it will make sure its sane.

>    b) What is the difference between calling DBCursor.size() and
> DBCuror.count()?

See the javadocs - count is total, size looks at skip/limit.

>    c) Is there a safe way to turn each chunk of results into an array?
> Something like
>             List<DBObject> results = new List<DBObject>();
>             while (cur.hasNext()) {
>                    List<DBObject> list = cur.toArray();
>                    results.addAll(list);
>                }


DBCursor has a toArray() method on it.

>    d) Any explanation why the performance varies so much for the same query?
>
>
> Code fragment:
>            ArrayList<Tuple> tuples = new ArrayList<Tuple>(200);
>            DB db = mongo.getDB(dbName);
>            if (db != null) {
>                db.requestStart();
>
>                DBCollection coll = db.getCollection(collectionName);
>                DBCursor cur = null;
>
>                cur = coll.find(dbQuery).addOption(Bytes.QUERYOPTION_SLAVEOK);
>                while (cur.hasNext()) {
>                    BasicDBObjectdbo = (BasicDBObject) cur.next();
>                    BaseTableRow row = new BaseTableRow(dbo);
>                    tuples.add(row.getTuple());
>                }
>                db.requestDone();
>            }
>


Could be various things. How/where are you measuring?
To make sure its from previous writes - do a getLastError right before
doing the query if measuring client side.

Joseph Wang

unread,
Sep 19, 2010, 10:02:00 AM9/19/10
to mongod...@googlegroups.com
Thanks for the response.


> 3) For the same query, timing for
> while (cur.hasNext())
> loop varies from 800ms to 20ms. Tried running profiling option on mongo
> server. Didn't see anything related to the collection.
> a) If mongo auto packs result up to 4M, is there a danger in specifying
> batchSize() that may return results that is greater than 4M?

Elliots wrote:
No - it will make sure its sane.

Does that mean that we will only gain performance improvement if we
know the result set is less than 4M?


> d) Any explanation why the performance varies so much for the same query?
>

Elliots wrote:
Could be various things. How/where are you measuring?
To make sure its from previous writes - do a getLastError right before
doing the query if measuring client side.

Simply running queries. No write. In production, we'll write to master only
and read from slaves. I'm simply counting time difference before
and after the while (cur.hasNext()) loop.



Joseph Wang

unread,
Sep 19, 2010, 11:04:47 AM9/19/10
to mongod...@googlegroups.com

On master and slave, I set maxConnection to 2000. On the webserver,
I add both master and slave to ArrayList<ServerAddress>. In the
collection.find(), I had set Bytes.QUERYOPTION_SLAVEOK option.
However, it seems the java driver only connects to master. In the quer


Both master and slave are running on port 10000.
[root@ip-10-160-26-159 ~]# netstat -an | grep 10000 | wc -l
2000
[root@ip-10-160-26-159 ~]# netstat -an | grep 10000 | grep -v 10.166.57.74 | wc
-l
0
[root@ip-10-160-26-159 ~]# netstat -an | grep 10000 | grep 10.166.57.74 | wc -l
2000


Connection code:
MongoOptions opt = new MongoOptions();
opt.autoConnectRetry = true;
opt.connectionsPerHost = 2000;

String[] servers = server_list.split(",");
ArrayList<ServerAddress> addr = new ArrayList<ServerAddress>();
int serverCount = 0;
for (int i = 0; i < servers.length; ++i) {
String[] serverInfo = servers[i].split(":");

try {
if (serverInfo.length == SERVER_INFORMATION_FIELD_SIZE) {
ServerAddress host = new ServerAddress(
serverInfo[SERVER_NAME_FIELD],

Integer.parseInt(serverInfo[SERVER_PORT_FIELD]));
addr.add(host);

serverCount++;
}
} catch (Exception ex) {

}
}

if (serverCount > 0) {
m = new Mongo(addr, opt);
}

Query code:

DBCollection coll = db.getCollection(collectionName);
DBCursor cur = null;

cur = coll.find(dbQuery).addOption(Bytes.QUERYOPTION_SLAVEOK);



Joseph Wang

unread,
Sep 19, 2010, 11:07:42 AM9/19/10
to mongod...@googlegroups.com
Also, when webserver started, there is only one connection to mongo.
Is there a way to specify min connection preestablish instead of on demand?


----- Original Message ----
From: Joseph Wang <joseph...@yahoo.com>
To: mongod...@googlegroups.com

Kyle Banker

unread,
Sep 20, 2010, 10:30:42 AM9/20/10
to mongod...@googlegroups.com
If you just want to connect to the slave, you must pass a single address to the Mongo constructor. Don't include the master.

Kristina Chodorow

unread,
Sep 20, 2010, 11:16:05 AM9/20/10
to mongod...@googlegroups.com
Does that mean that we will only gain performance improvement if we
know the result set is less than 4M?

batchSize isn't usually a great way of optimizing performance.

Does your query return different documents for different runs?  MongoDB will load the results of the query into memory, so subsequent identical queries should be faster.  However, if each query is getting random documents from the database, performance is going to vary a lot.


Joseph Wang

unread,
Sep 20, 2010, 1:15:07 PM9/20/10
to mongod...@googlegroups.com
Is the caching done on the driver side or server? How does Mongo figure
out if the the underlying cache result changed and it needs to invalidate
the cached result?

Seeing 300-600ms response for the same 5 queries whenever I restarted webapps.
Afterward, I'm getting faster response and faster execution of cur.hasNext()
loop.


From: Kristina Chodorow <kris...@10gen.com>
To: mongod...@googlegroups.com
Sent: Mon, September 20, 2010 8:16:05 AM
Subject: Re: [mongodb-user] Java driver questions

Joseph Wang

unread,
Sep 20, 2010, 1:19:53 PM9/20/10
to mongod...@googlegroups.com
This doesn't seem to be a good way to balance the load.

I assume there is no mechanism to establish actual connection
when calling new Mongo(addr, opt). I think this is part of
of the reason why the response time of inital queries are slow.


From: Kyle Banker <ky...@10gen.com>
To: mongod...@googlegroups.com
Sent: Mon, September 20, 2010 7:30:42 AM
Subject: Re: [mongodb-user] Re: Java connection pool bug?

Kyle Banker

unread,
Sep 20, 2010, 1:26:55 PM9/20/10
to mongod...@googlegroups.com
The Java driver doesn't support load balancing across multiple mongod instances, although it does support connection pooling for a single instance.

You can pass multiple nodes to Mongo(), but only to for replica set failover.

Kristina Chodorow

unread,
Sep 20, 2010, 1:27:03 PM9/20/10
to mongod...@googlegroups.com
Okay, it sounds like you're seeing a normal "warm up" pattern for the server.  When you start up the server, all of your data is on disk and none of it is in memory.  The server pulls the data it needs for the query from disk into memory.  So, when you start up MongoDB, the first couple queries will be slow as they have to copy the data from disk to memory.  After that, the queries will be faster because MongoDB doesn't have to go to disk.

The data gets evicted from memory in LRU order.  It's not really a cache in the way I think you're thinking of, it's just copies of pages of memory on disk (see http://en.wikipedia.org/wiki/Memory-mapped_file).  If you do a write, it'll update the "file" in memory.

Many people run a couple seed queries to populate their memory before making a MongoDB server live in production.

Joseph Wang

unread,
Sep 20, 2010, 1:31:21 PM9/20/10
to mongod...@googlegroups.com
If  each server's maxConnection is 500 and I specified opt.connectionsPerHost =1000,
will it connect to both servers?

Sent: Mon, September 20, 2010 10:26:55 AM

Joseph Wang

unread,
Sep 20, 2010, 1:36:26 PM9/20/10
to mongod...@googlegroups.com
Didn't restart mongo. Just webapp. Have tons of memory on mongo
and web. Thus, don't understand why only the performance of initial
queries are slow.


From: Kristina Chodorow <kris...@10gen.com>
To: mongod...@googlegroups.com
Sent: Mon, September 20, 2010 10:27:03 AM

Kyle Banker

unread,
Sep 20, 2010, 1:40:19 PM9/20/10
to mongod...@googlegroups.com
No. These are essentially unrelated. The driver will send requests only to a single mongod or mongos. It sounds like you want the driver to connect to multiple mongods and somehow distribute read requests. If this is what you need, you'll have to build that on top of the driver.

Eliot Horowitz

unread,
Sep 20, 2010, 10:29:17 PM9/20/10
to mongod...@googlegroups.com
Can you turn on db profiling to make sure its client side?
Might be creating the sockets or dns on the client side.

Eliot Horowitz

unread,
Sep 20, 2010, 11:42:07 PM9/20/10
to mongod...@googlegroups.com
From the shell can do:
db.setProfilingLevel(1,10)
Reply all
Reply to author
Forward
0 new messages