1
Given that new Documents and querys:
{
    "_id" : ObjectId("55803fd1cc0c9aa090e608be"),
    "song_name" : "Mickey is good",
    "time" : "3.56",
    "artist" : "Mickey"
}


{
    "_id" : ObjectId("55803fd1cc0c9aa090e608bf"),
    "song_name" : "Love is nothing",
    "time" : "5.56",
    "artist" : "Jimmy"
}

I need to find which songs have a title identical to the artist name. i have tried: db.myCollection.find( { $where: "this.artist == /this.song_name/" } );

but did not work out. please help`

2
  • what have u done so far, please share...
    – SSH
    Commented Jun 13, 2015 at 23:12
  • i have modified my query with what i did so far..
    – mrana
    Commented Jun 13, 2015 at 23:18

2 Answers 2

2

If I understand it well, you need to find all songs whose title contains the name of the artist. You don't need a regular expression for that1. As simple test using indexOf would suffice. Given your sample data:

> db.test.find({$where:
      "this.song_name.toLowerCase().indexOf(this.artist.toLowerCase()) > -1"
})

{ "_id" : ObjectId("557ccec684ee2ba0375f4fcf"),
  "song_name" : "Mickey is good",
  "time" : "3.56",
  "artist" : "Mickey" }

If you really need to find the songs whose title is equal to the artist name (you don't have such a document in your sample data), you would simply write:

> db.test.find({$where:
      "this.song_name.toLowerCase() == this.artist.toLowerCase()"
})

{ "_id" : ObjectId("557cd12284ee2ba0375f4fd1"),
  "song_name" : "The Monkeys",
  "artist" : "The Monkeys" }

Please note in either cases, I've normalized the strings using toLowerCase(). Depending your use case, you might need something much more sophisticated than that. For example, if you need to match "You and Me" by "You+Me".


1Using a regular expression here might even be harmful if the artist name contains meta-characters or quantifiers. For example, given the artist name "You+Me", the + here would be interpreted as 1 or more occurrence of the preceding character. So, matching "YouMe", "YouuuuuMe" but not the raw string "You+Me".

1

Anything inside the delimiters is considered a "String" and not a variable anymore. Also on the "Right Hand Side this comparison is not valid. So instead do

db.test.find({ "$where": " return new RegExp(this.artist,i).test(this.song_name);" })

So RegExp() compiles a pattern from the variable whereas // considers all contained to the a string literal. The .test() method is how you do the comparison to content with a regular expression for a "Boolean" result.

True that .indeOf() "should" be faster than a regular expression for basic strings, but if you need the case insensitive comparison then .toLowerCase() or .toUpperCase() introduce another cost of their own, so the negilgable difference is lost.

Also I think it just looks neater.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.