4

I am new in MongoDB.

I am programming an application with spring data and mongodb and I have one class with two fields: firstname and lastname.

I need one query for documents that contain one string in the full name (firstname + lastname).

For example: firstname = "Hansen David", lastname = "Gonzalez Sastoque" and I have a query to find David Gonzalez. In this example I expect there to be a match.

Concatenate two strings solves it but I don't know how to perform this.

Kemal Fadillah
  • 9,760
  • 3
  • 45
  • 63
  • Not really clear what you are after .. do you need to split your "firstname" and "lastname" strings into words and then search for all combinations? Or are you looking for substrings of the concatenation of the firstname and last name (eg "Hansen David Gonzalez Sastoque")? – Stennie Sep 17 '12 at 23:12
  • I am looking for substring(more exactly for contains) of the concatenation of the firstname and lastname. For example, look if "Hansen David Gonzalez Sastoque"(firstname+lastname) contains "David Gonzalez"(string to search in concatenation) – Hansen González Sep 18 '12 at 16:34

3 Answers3

5

Create a new array field (call it names) in the document and in that array put each name split by space. In your example the array would have the following contents:

  1. hansen
  2. david
  3. gonzalez
  4. sastoque

(make them all lower case to prevent case insensitivity issues)

Before you do your query, convert your input to lower case and split it by spaces as well.

Now, you can use the $all operator to achieve your objective:

db.persons.find( { names: { $all: [ "david", "gonzalez" ] } } );
Zaid Masud
  • 13,225
  • 9
  • 67
  • 88
2

You can use $where modifier in your queries:

db.users.findOne({$where: %JavaScript to match the document%})

In your case it may look like this:

db.users.findOne({$where: "this.firstname + ' ' + this.lastname == 'Gonzalez Sastoque'"})

or this:

db.users.findOne({$where: "this.firstname.match(/Gonzalez/) && this.lastname.match(/Sastoque/)"})

My last example does exactly what you want.

Update: Try following code:

db.users.findOne({$where: "(this.firstname + ' ' + this.lastname).match('David Gonzalez'.replace(' ', '( .*)? '))"})
Leonid Beschastny
  • 50,364
  • 10
  • 118
  • 122
  • This may achieve the result, but the [$where](http://www.mongodb.org/display/DOCS/Server-side+Code+Execution#Server-sideCodeExecution-NotesonConcurrency) will have a significant performance impact. `$where` evaluates JavaScript and [cannot take advantage of indexes](http://docs.mongodb.org/manual/reference/operator/where/). – Stennie Sep 23 '12 at 20:42
  • Yes. `$where` is much slower then indexable alternatives. It's why [Zaid Masud](http://stackoverflow.com/users/374420/zaid-masud) 's solution is much better, though it requires altering the database. – Leonid Beschastny Sep 23 '12 at 21:25
0

You should split your full name into a first name and a last name, then do your query on both fields, using the appropriate MongoDB query selectors.

ksol
  • 11,835
  • 5
  • 37
  • 64