epilef
epilef

Reputation: 63

MongoDB find documents using an array of objects as search argument

Is there a way to search a mongodb database using an array of objects as search arguments?

Lets say I have the following search preferences:

preferences = [{
    product: "PRODUCT_A",
    minqty: 5,
    maxqty: 50
  },
  {
    product: "PRODUCT_B",
    minqty: 100,
    maxqty: 500
  }
]

In my database I have Jobs with the following structure:

{
  jobName: "job name",
  items: [{
      product: "PRODUCT_A"
      qty: 25
    },
    {
      product: "PRODUCT_F"
      qty: 300
    }

  ]
}

I would like to query the database using preferences and returning any jobs that match at least one of the criteria's.

ATTEMPT 1:

I managed to use all my preferences as filters, but $match is cumulative, the way it's written it works like && in javascript. My goal is to have "match THIS || match THAT".

let pipeline = [];

preferences.map((item) => {
  let search = {
    product: item.product,
    quantity: { $gte: item.minqty, $lte: item.maxqty },
  };

  return pipeline.push({
    $match: {
      items: {
        $elemMatch: search,
      },
    },
  });
});

const jobs = await Job.aggregate(pipeline);

ATTEMPS 2 (SUCCESS):

let search = [];

preferences.map((item, index) => {
  let arguments = {
    product: item.product,
    quantity: { $gte: item.minqty, $lte: item.maxqty },
  };

  search.push(arguments);
});

let pipeline = [
  {
    $match: {
      items: {
        $elemMatch: {
          $or: search,
        },
      },
    },
  },
];

const jobs = await Job.aggregate(pipeline);

Upvotes: 1

Views: 105

Answers (1)

Gibbs
Gibbs

Reputation: 22974

Use aggregation

  1. Denormalize items using $Unwind
  2. Once denormalized, you can use simple match with $or
  3. Use $lte and $gte

And update the question with your attempts of these or post a new one.

Upvotes: 1

Related Questions