1

I'm trying to create an api which will return search results which match more than one parameter. I can query one parameter fine at the moment.

Here is an example url

http://localhost:3000/api/search?term=javascript&impact=sdg1

I want the results to include both term=javascript AND impact=sdg1

import Cors from "cors";
import initMiddleware from "../../util/init-middleware";
import { connectToDatabase } from "../../util/mongodb";

const cors = initMiddleware(
  Cors({
    methods: ["GET", "POST", "OPTIONS"],
  })
);

export default async function handler(req, res) {
  await cors(req, res);

  const { db } = await connectToDatabase();

 const data = await db
    .collection("jobs")
    .aggregate([
      {
        $search: {
          search: [
            {
              query: req.query.term,
              path: ["title", "role"],
            },
            {
              query: req.query.impact,
              path: ["impact"],
            },
          ],
        },
      },
    ])
    .sort({ date: -1 })
    .toArray();


  res.json(data);
}

Is this possible and can anyone suggest the right sort of query to write?

Many thanks in advance

user2095430
  • 83
  • 1
  • 8

1 Answers1

1

The way to accomplish this is with the compound operator. Here are the docs and here is how it would look in your code:

export default async function handler(req, res) {
  await cors(req, res);

  const { db } = await connectToDatabase();

 const data = await db
    .collection("jobs")
    .aggregate([
      {
        $search: {
          "compound": {
              "must": [{
                  "text": {
                      "query": req.query.term,
                      "path": ["title", "role"],
                    }
                  }],
               "filter":[{
                    "text": {
                      "query": req.query.impact,
                      "path": ["impact"],
                    }
                }]
           }
        },
      },
    ])
    .sort({ date: -1 })
    .toArray();


  res.json(data);
}
Nice-Guy
  • 1,457
  • 11
  • 20
  • dude. i tested it. And this does not work give the intended result. Must operator ignores the first `"text":{"query": req.query.term, path": ["title", "role"]}` and matches only with last `"text":{"query": req.query.impact,"path": ["impact"],}` – Firoj Siddiki Aug 21 '21 at 07:50
  • Take a look now – Nice-Guy Sep 02 '21 at 04:16