Your first design is actually very good. The reason is that you can index major , minor and patch fields for quick reading.
Querying the data is actually a lot easier than using the $and query. You can simply use the basic query for matching fields:
eg.
db.versions.find({major:1,minor:2,patch:20}) //give me documents of version 1.2.20 db.versions.find({major:1}) //give me all documents with major version 1 db.versions.find({major:1,minor:{$gte:2,$lte:5}}) //give me all documents of major version and minor versions between 2 and 5 inclusive.
You can create an index, for example
db.versions.ensureIndex({major:1,minor:1,patch:1})
The $and query is mainly intended for the case when you want to run a more complex query in the same field several times. For example, if you want to get major versions 1 and 2, you can use $and .
db.versions.find({major:1,major:2}) will actually return documents with major version 2. However, db.versions.find({a:$all:[1,2]}) will also work in this case . Ideally, you should avoid using $and if possible, because it actually generates multiple queries for each expression in the $and array and does the join. This is much more expensive than the sample requests above.
source share