0

I'm trying to create a search function where a user can input a certain query and find all messages that contain that query.

The way I have it set up is when the user clicks search, it sends a query to the database based on the current message they're in.

If I just do Messages.find() the data looks like this:

const input = [
  {
      "_id": "1",
      "firstName": "John",
      "last_name": "Doe",
      "message_id": "12345",
      "messages": [
          {
              "time": "Thu Aug 05 2021 19:31:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hey there"
          },
          {
              "time": "Thu Aug 05 2021 19:34:15 GMT-0700 (Pacific Daylight Time)",
              "text": "what's up"
          },
          {
              "time": "Thu Aug 05 2021 19:37:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hey"
          },
      ],
      "__v": 0
  },
  {
      "_id": "2",
      "firstName": "Jane",
      "last_name": "Doe",
      "message_id": "12345",
      "messages": [
          {
              "time": "Thu Aug 05 2021 19:32:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hey buddy"
          },
          {
              "time": "Thu Aug 05 2021 19:35:15 GMT-0700 (Pacific Daylight Time)",
              "text": "not much, what about you?"
          },
          {
              "time": "Thu Aug 05 2021 19:38:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hello!"
          },
      ],
      "__v": 0
  },
]

I want to search for a specific keyword "hey" and return the items that contain the word "hey"


const expected = [
  {
      "_id": "1",
      "firstName": "John",
      "last_name": "Doe",
      "message_id": "12345",
      "messages": [
          {
              "time": "Thu Aug 05 2021 19:31:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hey there"
          },
          {
              "time": "Thu Aug 05 2021 19:37:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hey"
          },
      ],
      "__v": 0
  },
  {
      "_id": "2",
      "firstName": "Jane",
      "last_name": "Doe",
      "message_id": "12345",
      "messages": [
          {
              "time": "Thu Aug 05 2021 19:32:15 GMT-0700 (Pacific Daylight Time)",
              "text": "hey buddy"
          },
      ],
      "__v": 0
  },
]

I'm currently doing it like this, but am wondering if there's a better way or if there's a way to do it with purely Mongoose.

  Message.find({message_id})
    .then((messages) => {
      let filtered = messages.map(item => {
        let filteredMessages = item.messages.filter(message => {
          return message.text.toLowerCase().match(new RegExp("\\b" + "hey" + "\\b")) != null;
        });
        return {...item, messages: filteredMessages};
      }).filter(empty => empty.messages.length > 0);

1 Answer 1

1

Hey Try this....

db.collection.aggregate([
  {
    $match: {
      "messages.text": {
        "$regex": ".*hey.*"
      }
    }
  },
  {
    $unwind: "$messages"
  },
  {
    $match: {
      "messages.text": {
        "$regex": ".*hey.*"
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      messages: {
        "$addToSet": {
          time: "$messages.time",
          text: "$messages.text"
        }
      },
      "firstName": {
        $first: "$firstName"
      },
      "last_name": {
        $first: "$last_name"
      },
      "message_id": {
        $first: "$message_id"
      },
      
    }
  },
  {
    $sort: {
      _id: 1
    }
  }
])

Output

[
  {
    "_id": "1",
    "firstName": "John",
    "last_name": "Doe",
    "message_id": "12345",
    "messages": [
      {
        "text": "hey",
        "time": "Thu Aug 05 2021 19:37:15 GMT-0700 (Pacific Daylight Time)"
      },
      {
        "text": "hey there",
        "time": "Thu Aug 05 2021 19:31:15 GMT-0700 (Pacific Daylight Time)"
      }
    ]
  },
  {
    "_id": "2",
    "firstName": "Jane",
    "last_name": "Doe",
    "message_id": "12345",
    "messages": [
      {
        "text": "hey buddy",
        "time": "Thu Aug 05 2021 19:32:15 GMT-0700 (Pacific Daylight Time)"
      }
    ]
  }
]

mongoplayground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.