Search code examples
arraysmongodbmongoosefull-text-search

MongoDB Full Text Search in an Array of objects


I have a Schema like this:

const AyoSchema = new Schema({
images: Array, 

Images is an array in which objects are stored in such format:

{
id: a uuid here, 
name: a string here,
url: a url here, 
topic: a string here 
}

What i want to do is, I want to search the name property of all objects in images array without invloving much work of indexes,

How shall i do?


Solution

  • There are a couple of ways you could handle it. If you want to return only the matching documents, it's a little more complicated.

    I assume you want to return only the matched items. In order to do so you will need to use the aggregation pipeline, specifically the $unwind and $match operators.

    Check out a live demo here

    Consider the following:

    Database

    [
      {
        _id: ObjectId("111111111111111111111111"),
        images: [
          {
            id: ObjectId("123123224454323123121314"),
            name: "foo",
            url: "cdn.domain.com/images/foo",
            topic: "lorem ipsum"
          },
          {
            id: ObjectId("222123224454323123121314"),
            name: "bar",
            url: "cdn.domain.com/images/bar",
            topic: "lorem ipsum"
          },
          {
            id: ObjectId("333323224454323123121314"),
            name: "baz",
            url: "cdn.domain.com/images/baz",
            topic: "lorem ipsum"
          }
        ]
      },
      {
        _id: ObjectId("222222222222222222222222"),
        images: [
          {
            id: ObjectId("888823224454323123121314"),
            name: "text",
            url: "cdn.domain.com/images/text",
            topic: "lorem ipsum"
          },
          {
            id: ObjectId("999993224454323123121314"),
            name: "foo",
            url: "cdn.domain.com/images/pic",
            topic: "lorem ipsum"
          }
        ]
      }
    ]
    

    Query

    db.collection.aggregate([
      {
        $unwind: "$images"
      },
      {
        $match: {
          "images.name": "foo" // <-- replace "foo" with your query
        }
      }
    ])
    

    Result

    [
      {
        "_id": ObjectId("111111111111111111111111"),
        "images": {
          "id": ObjectId("123123224454323123121314"),
          "name": "foo",
          "topic": "lorem ipsum",
          "url": "cdn.domain.com/images/foo"
        }
      },
      {
        "_id": ObjectId("222222222222222222222222"),
        "images": {
          "id": ObjectId("999993224454323123121314"),
          "name": "foo",
          "topic": "lorem ipsum",
          "url": "cdn.domain.com/images/pic"
        }
      }
    ]
    

    Update

    To include regex.

    Live demo

    Query

    db.collection.aggregate([
      {
        $unwind: "$images"
      },
      {
        $match: {
          "images.name": {
            "$regex": "fo*"
          }
        }
      }
    ])