Search code examples
node.jsregexmongodbmongoosetext-search

MongoDB - How can I find all other related documents from all collections. I have access to only 1 id


Hello I am using mongoose to search for similar posts in my collection.

/*Product model*/

    const productSchema = mongoose.Schema(
      {
        writer: {
          type: Schema.Types.ObjectId,
          ref: "User",
        },
        title: {
          type: String,
          maxlength: 50,
        },
        description: {
          type: String,
        },
        Category: {
          type: String,
          default: "Mobiles",
        }
    );

I can have access to only a single id at a time, what I want is to have access to all other posts

which have common string in their title, description or category.

In params I have only Product _id.

This is my code.

router.post("/MultiCards/:any", (req, res) => {
  let order = req.body.order ? req.body.order : "desc";
  let sortBy = req.body.sortBy ? req.body.sortBy : "_id";
  let limit = req.body.limit ? parseInt(req.body.limit) : 100;

  Product.find({ _id: req.params.any })
    .sort([[sortBy, order]])
    .limit(limit)
    .exec((err, products) => {
      if (err) return res.status(400).json({ success: false, err });
      res
        .status(200)
        .json({ success: true, products, postSize: products.length });
    });
});

Solution

  • If you really only have access to _id of the product then find this product and then use the returned object to search for similar products with find

    router.post("/MultiCards/:any", (req, res) => {
      let order = req.body.order ? req.body.order : "desc";
      let sortBy = req.body.sortBy ? req.body.sortBy : "_id";
      let limit = req.body.limit ? parseInt(req.body.limit) : 100;
    
      Product.findById(req.params.any)
        .sort([[sortBy, order]])
        .limit(limit)
        .exec((err, product) => {
          if (err) return res.status(400).json({ success: false, err });
          Product.find({ Category: product.Category}).then((products) => {
           res
            .status(200)
            .json({ success: true, products, postSize: products.length });
          })
    
        });
    });
    
    

    ES2016 Version

    router.post('/MultiCards/:any', async (req, res) => {
      const order = req.body.order ? req.body.order : 'desc';
      const sortBy = req.body.sortBy ? req.body.sortBy : '_id';
      const limit = req.body.limit ? parseInt(req.body.limit) : 100;
      try {
        const product = await Product.findById(req.params.any).sort([[sortBy, order]])
          .limit(limit).exec();
        const products = await Product.find({ title: `/${product.title}/i` });
        res
          .status(200)
          .json({ success: true, products, postSize: products.length });
      } catch (error) {
        res.status(400).json({ success: false, error });
      }
    
    

    If you want similar do a query like this one /query/i

    as written in mongoose docs

    // executes, name LIKE john and only selecting the "name" and "friends" fields
    MyModel.find({ name: /john/i }, 'name friends', function (err, docs) { })