Reputation: 1334
I have a collection of documents with the following structure in Mongo using Meteor:
{
...
Name: 'Jane Doe',
Finances: {
Owed: 0,
Due: 0,
Paid: [
[400, 'Oct 2015'],
[300, 'Jan 2016'],
[500, 'Mar 2016']
]
},
Address: '123 Mains Street',
...
}
I'd like to return all the documents that have a payment value made in 2016. So, in this example, the document above would indeed be returned since it has at least one sub-array [, 'Jan 2016'] within the 'Paid' property. How could I set up the query in Mongo?
I tried something like:
Collection.find({ 'Finances.Paid[0]': { $regex: '2016' } });
But I'd need to go through all the inner arrays within 'Paid' to check. Can I do this strictly in Mongo?
Upvotes: 1
Views: 789
Reputation: 5539
Is difficult with this schema design.
Mongo is not designed to query well, a list which stores lists that stores different types of values i.e. [400, 'Oct 2015'].
Better will be for queries to design the Finances
field like this:
Finances: [
{ 'a': 400, 'b': 'Oct 2015'},
{ 'a': 300, 'b': 'Oct 2016'},
{ 'a': 500, 'b': 'Oct 2016'}
]
Than you can do queries like:
db.Collection.find({ "Finances.Paid.b": { $regex:'2016'}})
With your schema you can do it with aggregation:
db.Collection.aggregate([
{
$unwind: '$Finances.Paid'},
{
$match: {'Finances.Paid':{ $regex: '2016' }}
},
{
$group: {
_id:'$_id',
Name: {'$first': '$Name'},
Address: {'$first': '$Address'},
Finances: {'$first': '$Finances'}
}
},
]);
query result:
{
"_id" : ObjectId("580fb7d6c37ebe91b0f943df"),
"Name" : "Jane Doe",
"Address" : "123 Mains Street",
"Finances" : {
"Owed" : 0,
"Due" : 0,
"Paid" : [
300,
"Jan 2016"
]
}
}
That will return all the documents that have a payment value made in 2016, the drawback is that returns only one payment from 2016, the first one that it founds.
Upvotes: 2
Reputation: 7777
I haven't tried this code with your data, but you should be able to do it with something like this
Collection.find({ Finances: {$elemMatch: {Paid: {$regex:'2016'}}}})
It should scan the array of Paid elements
Edit: Try this
Collection.find({ "Finances.Paid": {$elemMatch: { $regex:'2016'}}})
See https://docs.mongodb.com/v3.2/reference/operator/query/elemMatch/ for an explanation of $elemMatch
Upvotes: 0