Allu Manikyam
Allu Manikyam

Reputation: 461

How to match the two strings with and without including spaces

For example: In DB I've the string value like "cell phones". If I get the string value like "cellphones" from frontend. How can I compare it with DB string and get the related string values in response.

Upvotes: 15

Views: 1842

Answers (10)

Ashh
Ashh

Reputation: 46451

If you need some aggregation trick then you can try this

db.collection.aggregate([
  { "$project": {
    "name": {
      "$reduce": {
        "input": { "$split": ["$name", " "] },
        "initialValue": "",
        "in": { "$concat": ["$$value", "$$this"] }
      }
    }
  }},
  { "$match": { "name": "cellphones" }}
])

You can test it Here

Upvotes: 6

Tripura
Tripura

Reputation: 96

Just remove those spaces from the response you are getting after query find then pass the response to require input field. Then match that string with front-end or input string. If both matches load the required content. Suppose the collection name is Category. Then the sample query will be like this

Category.find().exec((err, categories) => {
         var details=[]
         var matchCategory=[]
         categories.map((category,key)=>{
           var obj ={}
           obj.name = category.name.toLowerCase().replace(/\s/g, "")
           details.push(obj);
         })
       if(details.length > 0){
         var detailsLength=details.length
         details.map((category,key)=>{
             if(category.name=="cellphones"){ // match your input string 
               matchCategory.push(category)
             }
             detailsLength--
         })
         if(detailsLength==0){
               resolve(matchCategory);
         }
       }
     })

This may help you to reach out.

Upvotes: 4

Anthony Nandaa
Anthony Nandaa

Reputation: 3400

You can first start by stripping out the spaces on both the strings before comparing them, for example:

let a = "cell phone";
let b = "cellphone";
let c = "cell phones"

const stripSpaces = s => s.replace(/\s/g, '');

// compare
console.log(stripSpaces(a) == stripSpaces(b)); // true
console.log(stripSpaces(a) == stripSpaces(c)); // false

Upvotes: 5

Chandra
Chandra

Reputation: 166

May be it solves Your problem

   Take Device_Names column contains 

               "cell phone"
               "mobile phone"
               "cellphone"
               "laptop"

1.) Normal way:

    select Device_Name from devices where Device_Name='cellphone' ;

             result: 
                    "cellphone"

      which is third one

2.)By Remove spaces:

  SELECT  Device_Name FROM devices WHERE REPLACE(Device_Name, ' ', '')='cellphone'

               result: 
                    "cell phone"
                    "cellphone"

       which includes first and third one

Upvotes: 2

YLS
YLS

Reputation: 717

Answers below this question are good, like using where and Regex, but might be at their best if you got a small number of docs that you may want to query from.

If you got many docs, I'd suggest you: 1. Use an extra field like cellphone without any space, if the values of the original field are expected to be short. 2. Try using search engines, like ElasticSearch, or MongoDB's own text search, to find what you need, not only cell phone to cellphone, but mobile phone even smartphone. Actually, when you google something, the suggestions while you're typing are also coming from similar but more complex algorithms.

Upvotes: 4

dnickless
dnickless

Reputation: 10918

Given a document like this:

{
    "text" : "cell phones"
}

You could use the $where operator like this:

db.collection.find({
    $where: function() {
        return this.text.replace(' ', '') == "cellphones"
    }
});

I wouldn't necessarily recommend this for big collections (performance might not be great). However, even with big collections you could supposedly achieve some pretty ok performance by adding an extra filter on the "text" field to filter out all documents that don't start with the correct first character(s):

db.collection.find({
    "text": { $regex: "^" + "cellphones".charAt(0) }, // this will use an index on the "text" field if available
    $where: function() {
        return this.text.replace(' ', '') == "cellphones"
    }
});

Or perhaps even this version with yet another filter in the $where bit that checks the string lengths for a reduced number of string comparisons:

db.collection.find({
    "text": { $regex: "^" + "cellphones".charAt(0) }, // this will use an index on the "text" field if available
    $where: function() {
        return this.text.length >= "cellphones".length // performance shortcut
               && this.text.replace(' ', '') == "cellphones"
    }
});

Upvotes: 3

Mohammadreza  Alagheband
Mohammadreza Alagheband

Reputation: 2230

try replacing empty string from query string first, and then compare to the field as

db.test.find(function() { 
    return this.data(function(elm) {
        "cell phones".replace(/ /g,"") == elm.name
    });
});

Upvotes: 2

Anthony Nandaa
Anthony Nandaa

Reputation: 3400

You can first start by stripping out the spaces on both the strings before comparing them. I'm assuming you don't know which one has spaces before hand, so you will run all the values through the stripSpaces function, for example:

let a = "cell phone";
let b = "cellphone";
let c = "cell phones"

const stripSpaces = (s) => s.split(' ').join('');

// compare
console.log(stripSpaces(a) == stripSpaces(b)); // true
console.log(stripSpaces(a) == stripSpaces(c)); // false

Upvotes: 2

Denis Kuratovich
Denis Kuratovich

Reputation: 287

You can compare so:

let val1 = 'cell phones';
let val2 = 'cellphones';

console.log(val1.replace(/\s/g, '') === val2.replace(/\s/g, '')) // true
//OR
console.log(val1.split(' ').join('') === val2.split(' ').join('')) // true

Upvotes: 10

Orelsanpls
Orelsanpls

Reputation: 23515

You can use of a regex when looking for your value, like :

cellphones|cell phones

Collection.find({
  someName: {
     $regex: new RegExp('cellphones|cell phones', ''),
  },
});

Upvotes: 1

Related Questions