简体   繁体   中英

how to find if a field contains a string in a field from mongoDB

I have a problem that I can get a data from mongoDB but it's not what i want.

I just want to get a data, if datas have "#l" sting in the message field, I want it.

here's data on mongodb

({...someData, message: 'asdfff #lol blah blah blah hellohellohellohello'})
({...someData, message: '#lol asdfff blah blah blah byebyebye'})
({...someData, message: 'asdfff asdffasfdah blah blah #lol hello'})
({...someData, message: 'asdfff #l blah blah blah hello'})
({...someData, message: 'asdfff #lo blah blah blah hello'})

here's what i've done

const hashtagPosts = await Post.aggregate([
      {
        $match: {
          message: { $regex: `#${hashtag}` },
        },
      },
      {
        $sort: {
          createdAt: -1,
        },
      },
      {
        $limit: 10,
      },
    ]);
    const hashtagPosts = await Post.find({
      message: { $regex: `#${hashtag}` },
    });

and If I run these code with "#l" this hashtag I will get this data

({...someData, message: 'asdfff #lol blah blah blah hellohellohellohello'})
({...someData, message: '#lol asdfff blah blah blah byebyebye'})
({...someData, message: 'asdfff asdffasfdah blah blah #lol hello'})
({...someData, message: 'asdfff #l blah blah blah hello'})
({...someData, message: 'asdfff #lo blah blah blah hello'})

What I want, the result

({...someData, message: 'asdfff #l blah blah blah hello'})

if I search with "#l" this searchword I want to get datas that contain exact the same searchword like "#l" => "#l"

not contain "#lol" "#lo" is it possible? I have no idea how can i get datas like that. thanks for reading my question.

You just need to change your regex, if you want to allow any match precending #l except a letter you could use the negative lookahead syntax like this :

message: { $regex: `#l(?![a-zA-Z])` },

And you can add any "illegal" characther to the group.

If all you want is exact match for #l it's much easier, we either allow a space or end of string, like this :

message: { $regex: `#l($|\s)` },

(I didn't deal with the precending edge case under the assumption no string will be like #hashtag#l , but using the same technique you an ensure the tokens you want before it are there.

MongoDB Playground with example Above answer explanation is correct.

DB Record:

   [
  {
    "key": 1,
    "message": "asdfff #lol blah blah blah hellohellohellohello",
    
  },
  {
    "key": 2,
    "message": "#lol asdfff blah blah blah byebyebye"
  },
  {
    "key": 3,
    "message": "asdfff asdffasfdah blah blah #lol hello"
  },
  {
    "key": 4,
    "message": "asdfff #l blah blah blah hello"
  },
  {
    "key": 5,
    "message": "asdfff #lo blah blah blah hello"
  }
]

Aggregation Query:

db.collection.aggregate([
  {
    $match: {
      "message": {
        // put your query in $regex option
        $regex: "#l(?![a-zA-Z])",
        
      }
    }
  }
])

Output Screenshoot: 输出

You can do it like this way.

const hashtagPosts = await Post.find({
      message: /#l/i
    });

Another way to do this.

const hashtagPosts = await Post.find({
      message:  { "$regex": "#l", "$options": "i" }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM