Home > front end >  Mongoose find all elements that matches field plus any object in list (MongoDB)
Mongoose find all elements that matches field plus any object in list (MongoDB)

Time:10-22

I can't find how to get all documents that matches by critera. I have 1 field called Id:

parent = 1

And a list with these combinations:

[
  { year: 2021, month: 1 },
  { year: 2021, month: 0 },
  { year: 2020, month: 11 },
  { year: 2020, month: 10 }
]

The documents looks like this:

id: Id
parent: Id
year: Number
month: Number

And I'm trying to find ALL documents that matches parent and where month and year both matches ANY 1 from the list.

Any idea? I've tried with elemMatch but with no success.

const foundDocuments = await Document.find({
    parent, results: { $elemMatch: { list } },
});

example data:

[
    {id: 4, parent: 1, year: 2021, month: 5 },
    {id: 5, parent: 1, year: 2021, month: 4 },
    {id: 6, parent: 1, year: 2021, month: 3 },
    {id: 7, parent: 1, year: 2021, month: 2 },
    {id: 8, parent: 1, year: 2021, month: 1 },
    {id: 9, parent: 1, year: 2021, month: 0 },
    {id: 10, parent: 1, year: 2020, month: 11 },
    {id: 11, parent: 1, year: 2020, month: 10 },
    {id: 12, parent: 1, year: 2020, month: 9 },
    {id: 13, parent: 2, year: 2021, month: 1 },
    {id: 14, parent: 2, year: 2021, month: 0 },
    {id: 15, parent: 2, year: 2020, month: 11 },
    {id: 16, parent: 2, year: 2020, month: 10 },
    {id: 17, parent: 2, year: 2020, month: 9 },
]

expected output:

[
    {id: 8, parent: 1, year: 2021, month: 1 },
    {id: 9, parent: 1, year: 2021, month: 0 },
    {id: 10, parent: 1, year: 2020, month: 11 },
]

CodePudding user response:

Since you are using JS you can create the query to add all pair values into a list like this:

const list = [
    { year: 2021, month: 1 },
    { year: 2021, month: 0 },
    { year: 2020, month: 11 },
    { year: 2020, month: 10 }
  ]
const parentId = 1

var findObj = {
  parent:parentId, 
  $or:list.map(m => {
    return {year:m.year,month:m.month}
  })
}
console.log(findObj)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Here the find object is the same as used in this example query so you only need to add into a query

const foundDocuments = await Document.find(findObj);

Note how the trick in the query is to do an $or with all possible pair values. Also, your expected output does not include id 11. Is that a mistake?

  • Related