-1

NOT [DUPLICATE]: This question is NOT been previously answered and been unfairly downvoted. The two marked answers from different sources are about distinct things. Combined, they may partially answer to some degree but they don't address the very specific case of what is been asked here (e.g. None of them explains how to parse email before comparing to variable). I need to extract the first half of email, compare it to a string variable, and then execute the query with mongoose.

I found many partial answers for this question (/^([^@]*)/) but nothing showing how to apply the filter to a search given string for a partial email field and in a Mongoose query.

With this I have a search (provided by user) but not the filter:

{ email: { $regex: search, $options: "i" } }

With this I have a filter but not the search:

{ email: { $regex: /^([^@]*)/, $options: "i" } }

I need to find a way to do both at same time in one go (to search only first half of email with given string variable). My intention is to disregard everything that comes after the @ symbol (including the @) which should not be included in a string variable ("search"). I need to find a way to insert search in the regex filter.

Again, it should ignore/exclude everything from '@' to the end of the email address (the search should not consider this part).

  • search is a variable

Thanks in advance!

Fabricio
  • 828
  • 8
  • 13
  • Do you mean `{ email: { $regex: new RegExp("^[^@]*" + search, "i") } }`? – Wiktor Stribiżew Sep 25 '18 at 13:02
  • Thanks for answering. I've just tried that but did not work. Meaning, it included the domain part of the email in the results when it shouldn't. I edited my question to make it more clear. – Fabricio Sep 25 '18 at 13:42
  • There are really a lot of quesitons, but not sure they will work for you. Check [this](https://stackoverflow.com/questions/14199529/mongoose-find-modify-save) or [this one](https://stackoverflow.com/questions/21138167/how-to-search-and-replace-in-mongoose). – Wiktor Stribiżew Sep 25 '18 at 14:01
  • Thanks again, for trying. But I am not trying to replace or update anything. It's supposed to be a "simple" find (query). The only issue is in how to query not the whole email field but only the first half (e.g.: including "my.first_name" but excluding/ignoring "@google.com"). – Fabricio Sep 25 '18 at 14:17
  • @Wiktor Really, why are you doing this? First you complained about John's answer and now you are making false assumptions about my question? I thought we had it cleared out before. Those two "answers" are about two different things. Those may help answering to some degree but they don't help solving this specific issue. John managed to do that by rewriting everything. – Fabricio Sep 26 '18 at 20:25

1 Answers1

1

/^[^@]*search/ would do the trick. This searches for a literal match search from the start of the string. As long as the characters between the start of the string and search aren't an @ character. This means "foo bar search" would hit, but "foo@bar search" doesn't.

If search is a variable you might want to give Javascript Regex: How to put a variable inside a regular expression? a look.


Combining the above two options you'll get:

var regex = new RegExp('^[^@]*' + search);
User.find({email: {$regex: regex, $options: "i"}});

However, if search contains user content that should not be interpreted as regex you should escape the contents like so:

// Assuming that the following helper is present.
RegExp.escape = function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};

var regex = new RegExp('^[^@]*' + RegExp.escape(search));
User.find({email: {$regex: regex, $options: "i"}});

MongoDB also allows a string to be passed as $regex value. Therefore creating a JS RegExp object is unnecessary and you could simplify the above to:

User.find({email: {$regex: '^[^@]*' + RegExp.escape(search), $options: "i"}});
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • search is a variable containing a given string the user provides in the front-end. I am trying to search for this string in the email but only its first half. – Fabricio Sep 25 '18 at 13:40
  • I've updated the answer, redirecting to another SO question how to put variables inside your regex. – 3limin4t0r Sep 25 '18 at 13:43
  • I've noticed and also updated my question to clarify that. Thanks. I will now have a look in the link you provide and will come back to answer you again. – Fabricio Sep 25 '18 at 13:49
  • This is not about putting a variable into regex. If you think that is the only issue, the question should be closed as a dupe, no need repeating what has already been answered. However, OP needs a different solution (though including the variable passing to the regexp, too). – Wiktor Stribiżew Sep 25 '18 at 13:59
  • I don't think that link helps me because although the title talks about how to put variable inside regex, it actually talks about replacing variable contents. – Fabricio Sep 25 '18 at 14:02
  • @WiktorStribiżew Seems like you don't understand my answer. The regex shows how it should be searched for (answering OPs question). Combining my answer with the linked answer to put a variable into the regex should yield the wanted result. – 3limin4t0r Sep 25 '18 at 14:05
  • I understand it well. It is exactly the same as [my suggestion](https://stackoverflow.com/questions/52498822/how-to-query-first-half-of-email-until-with-given-string-using-regex-in-mong/52499390?noredirect=1#comment91938201_52498822) and [OP says it does not work](https://stackoverflow.com/questions/52498822/how-to-query-first-half-of-email-until-with-given-string-using-regex-in-mong/52499390?noredirect=1#comment91939913_52498822). – Wiktor Stribiżew Sep 25 '18 at 14:07
  • @WiktorStribiżew However your suggestion was not an answer. Furthermore this answer was posted before OP said that the suggestion didn't work. – 3limin4t0r Sep 25 '18 at 14:09
  • @Fabricio I updated the anser with possible use case examples. – 3limin4t0r Sep 25 '18 at 14:17
  • 1
    @WiktorStribiżew In my opinion this doesn't deserve a downvote though. *"Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect." - [Stack Overflow Help Center](https://stackoverflow.com/help/privileges/vote-down)* This answer does not meet those criteria, of course you're free to leave your downvote. I'm merely pointing out the obvious. – 3limin4t0r Sep 25 '18 at 14:35
  • @John I really appreciate your effort. I just tried both, with and without "escape" but it is giving zero results (it is neither matching the first half or the ending of the email). Perhaps there is some tiny typo somewhere there? – Fabricio Sep 25 '18 at 14:35
  • @Fabricio You've `{ { email: { $regex: /search/^([^@]*)/, $options: "i" } } }` in your question (which I've copied), shouldn't that be `{ email: { $regex: /search/^([^@]*)/, $options: "i" } }` (one pair of curly braces removed)? It doesn't seem like valid JS to me. I'll update the answer and remove the extra set of curly braces. – 3limin4t0r Sep 25 '18 at 14:43
  • @John: Good eyes. I did put an extra pair of curly braces in the question but not in my code, and I also noticed you added those in your answer and I removed them when I tried. I will update my question correcting this issue now but that is still not the problem, I'm afraid. :( – Fabricio Sep 25 '18 at 14:52
  • @Fabricio I can't help you any further in that case. I would double check the database record that you're trying to match with the input that you're providing to the query. – 3limin4t0r Sep 25 '18 at 14:58
  • @John: This alone is not working: var regex = new RegExp('^[^@]*' + search); User.find({email: {$regex: regex, $options: "i"}}); – Fabricio Sep 25 '18 at 15:03
  • @John: Thanks for trying! Everything is working fine with other fields, and even with the whole email during the search (using regex and everything). The only issue is indeed doing this half email thing. – Fabricio Sep 25 '18 at 15:04
  • @John: Example: I have the email "ghost@test.com". It works (returns the document) when I search for "ghost" or "test" with this { email: { $regex: search, $options: "i" } }. But it does not work (returns nothing) when I search for "ghost" when using the solution you proposed. – Fabricio Sep 25 '18 at 15:12
  • @John: I was doing some tests (and thinking) and I realized that it may have to be done in two steps, like first the regex filter in the email address (stored in MongoDB) and only then comparing its result with the search variable. I just don't know yet how to do it in a mongoose find query. – Fabricio Sep 25 '18 at 15:51
  • @Fabricio I assumed the `search` variable is a string, is that the case? Have you tried hard coding the variable to see if that works? eg. `User.find({email: {$regex: '^[^@]*ghost', $options: "i"}});` – 3limin4t0r Sep 25 '18 at 16:17
  • @John. Thanks for asking me that. `search` is a string indeed but you questioning me that made me have another look in the code and realize I was doing this `const search = srch && srch.length > 0 ? '.*${srch}.*' : '';` before reaching our regex code. So, it was doing `new RegExp('^[^@]*' + search)` on top of `.*${srch}.*`. I corrected that and t's all working fine now! :) Sorry for my mistake in not noticing that earlier!! – Fabricio Sep 25 '18 at 16:48
  • @Fabricio Glad you found your solution. Don't forget that if your variable is user provided and you don't want it to be interpreted as regex you should escape the regex chars as shown in my answer. – 3limin4t0r Sep 25 '18 at 17:30
  • @John: Yes, I got that. I updated every controller (in the backend) to escape the regex chars. Two strikes with one shot. It's all good now. – Fabricio Sep 25 '18 at 19:01