Reputation: 1725
A 5,000 to 10,000 record Mongo collection contains:
{
"_id" : ObjectId("55e16c34c78b04f43f2f55a0"),
"appID" : NumberInt(4830800),
"topics" : {
"test1" : 1.440899998865E12,
"test2" : 1.440899998865E12,
"test3" : 1.440899998865E12,
"test4" : 1.440899998865E12
},
}
I need to query for records that contain a specified property name in the topics field and where the value of the specified name is greater than or equal to a given number.
something like
find({"topics.test1": { $gte: 1440825382535 }})
This query works as expected, returning a set of records that have a test1 property with a test1 value >= 1440825382535
If I create a simple index on the topics field explain()
says that no index is used for the query (understandably).
The set of property names that may be searched for is not predefined. The query is dynamically built based on names that are found elsewhere.
Is there a way to index this table to speed up queries? The full scan query takes quite a bit of time to run (on the order of 1.5 seconds).
Upvotes: 3
Views: 818
Reputation: 311835
To make this type of data indexable, you need to change the schema to make topics
an array and move the dynamic test1
, test2
, etc. keys into values.
So something like:
{
"_id" : ObjectId("55e16c34c78b04f43f2f55a0"),
"appID" : NumberInt(4830800),
"topics" : [
{name: "test1", value: 1.440899998865E12},
{name: "test2", value: 1.440899998865E12},
{name: "test3", value: 1.440899998865E12},
{name: "test4", value: 1.440899998865E12}
]
}
Then your query changes to:
find({topics: {$elemMatch: {name: 'test1', value: {$gte: 1440825382535}}}})
Which you can support with an index of:
{'topics.name': 1, 'topics.value': 1}
Upvotes: 2
Reputation:
Was a little confused at what you were trying to do, but maybe something like this?
find({"topics.test1": {$exists: true}, { $gte: 1440825382535 }})
Upvotes: 1