Mongodb - Query MultiKey Indexed Documents - mongodb

My question is about the way MongoDB operates when querying MultiKey document.
Assuming I have these documents:
{
a: 1,
b: 2,
c: ['x','y','z']
},
{
a:3,
b: null,
c: ['x','z']
}
My query is this:
db.<collection>.find({ b: null, c: 'x'})
And my index is:
db.<collection>.ensureIndex({ c: 1 })
My question is: For the query above (that asks for c AND b), how does MongoDB invokes the query? Does it 'see' that I have an index on c or does it try to only look for an index for both c AND b ?

Thanks Disposer
The query just finds the index of c even if the statement includes c and b.

Related

How to create index for the following kind of data in mongodb

db.test.insert({a:1, b:[1])
db.test.insert({a:1, b: 1})
db.test.insert({a:[1], b: 1})
db.test.insert({a:[1], b: [1]})
what should be a right way to index the fields so that i can query over a and b?
{ _id: 1, a: [1, 2], b: 1, category: "A array" }
{ _id: 2, a: 1, b: [1, 2], category: "B array" }
A compound multikey index { a: 1, b: 1 } is permissible since for each
document, only one field indexed by the compound multikey index is an
array; i.e. no document contains array values for both a and b fields.
However, after creating the compound multikey index, if you attempt to
insert a document where both a and b fields are arrays, MongoDB will
fail the insert.
---- Documentation
But one of your doc's a & b both contain array.

MongoDB index ascending or descending matter

In MongoDB if I run a query like the following to get the latest trade:
db.trades.find({ sym: 'AAPL' }).sort({ d: -1 }).limit(1)
If the index on d is created as { d: 1 }. I.E. does it matter if the index sort is ascending or descending? Also, I have an index on sym as well { sym: 1 }.

What are the tradeoffs of creating a new compound index versus adding to an existing?

I'm querying by fields a,b, and c, and have this index:
{a: 1, b: 1, c: 1}
I'm adding a new query on a, sorted by d desc. Should I change the index to:
{a: 1, b: 1, c: 1, d: -1}
Or should I add a second index:
{a: 1, d: -1}
In this case, changing the index doesn't work (see http://docs.mongodb.org/manual/tutorial/sort-results-with-indexes/#sort-and-non-prefix-subset-of-an-index).
In the general case of querying non-sequential compound index fields, while creating indexes always takes up more memory, it will perform better:
"However, the index would not be as efficient in supporting the query as would be an index on only item and stock."
http://docs.mongodb.org/manual/core/index-compound/

MongoDB query with condition on multiple records

This might be trivial, but I haven't figured out a way to do it.
Say I have the following records in the database:
{ A: 1, B: 2, C: "Red" }
{ A: 1, B: 2, C: "Blue"}
{ A: 1, B: 3, C: "Red" }
And I want to return all records with {A: 1, C: "Red"}, but not when C: "Blue" if there are multiple records with the same B values. So for the above records, it'll only return the 3rd record. The 1st record would not be returned because there are two records with the same B value, and one of them has C: "Blue" as a value.
I can only think of doing this via two queries to the database, i.e. first query {A:1, C:"Red"}, then check by querying all elements in database. I suppose the second step might actually be many more than just 1 query.
I don't really want to query with {A: 1}. Of course, I'm doing all this through the API, so this way it'll be one database query, but the resulting list could be much bigger than I'd like.
Is there a query that can do what I want via just 1 database call? Thanks.
I don't think it's possible with one query. But you can get all B you want with aggregate and then query database for that B:
db.test1.aggregate(
[
{$group: {_id: "$B", count: {$sum:1}}},
{$match: {count:1}}
]
)
will return you all B for which there only one record in your collection.

MongooseJS Query select attributes of subdocument

Given a model foo with the following schema;
{
a: String,
b: [{c: String, d: String}]
}
Assume the values of a are unique, and assume the values of c in a given foo document are unique. If I had values A and C of a and c respectively, then A uniquely identifies a foo document, and C uniquely identifies a foo.b sub-document. Is it possible then, to forge a query that returns to me the value of d?
Conceptually,
foo ----(find({a:A}))-----> foo_document -----(find({c:C}))------>foo_subdoc-------(select(d))---->value_of_d
Enough information is given, I just don't know if Mongoose has a a mechanism for this.
You can use the $elemMatch projection operator to identity the matching b element to include:
foo.find({a: A}, {b: {$elemMatch: {c: C}}}, function(err, doc) {
// doc.b[0].d contains the value of d you're looking for.
});