Reputation: 35
Not sure if this is possible, but here goes.
I have a MongoDB (using morphia to access it) with a table like the following (simplified for this example, but the concept is the same):
{name:"Product A", parts:[{sku:"W-01"},{sku:"Y-01", qty:2}]}
{name:"Product B", parts:[{sku:"X-02"},{sku:"W-02"}]}
{name:"Product C", parts:[{sku:"Z-01"}]}
Now I want to find products with parts of which sku starts with "Y" or "Z". For the above docs, the first and third should be returned.
One possible query I can imagine is like this:
{$or:[{"parts":{"$elemMatch":{sku:/Y.*/}}},{"parts":{"$elemMatch":{sku:/Z.*/}}}]}
This needs to loop through the query arrays ["Y","Z"]
Is there any other way to do this? :)
Upvotes: 0
Views: 102
Reputation: 36784
Instead of doing a regular expression match, you could split out the first letter its own subkey as well:
{
name:"Product A",
parts: [
{ s: "W", ku: "W-01" },
{ s: "Y", ku: "Y-01", qty:2 }
]
}
Otherwise you can simply do this regular expression match — you don't need the $elemMatch
here either.
db.products.find( { "parts.sku: /^[YZ]/ } );
But it is better to use an $or
for each of them, as then at least a little bit of the index can be used as the regular expression search is now a fixed-prefixed regular expression that internally gets rewritten to a range query (Y <= x < Z
) or (Z <= x < [
):
db.so.ensureIndex( { 'parts.sku': 1 } );
db.products.find( { $or: [
{ "parts.sku": /^Y/ },
{ "parts.sku": /^Z/ }
] } );
Upvotes: 1