Search 2 text fields as 1 field
Sounds mostly like you want text search . Text indexes can span multiple fields, so the entered terms from all indexed fields will be entered:
db.collection.ensureIndex({ "firstName": "text", "lastName": "text" })
db.collection.find({ "$text": { "$search": "Peter Robert" } })
This is one way to deal with it. Other matches will also return, but exact matches have the highest score so you can rank them.
Alternatively, if you know that, in that order, you always get a string like "Peter Robert", you can always "split" and tokenize the input:
var input = "Peter Robert";
var parts = input.split(/ /); // splits on space
db.collection.find({
"firstName": parts[0],
"lastName" parts[1]
])
It's all pretty simple. Or even to apply the operator and in the mix: $regex
$or
var input = "Peter Robert";
var regexStr = input.split(/ /).join("|"); // make it like "Peter|Robert"
db.collection.find({
"$or": [
{ "firstName": { "$regex": regexStr } },
{ "lastName": { "$regex": regexStr }}
]
})
Honestly, you can even do it with an operator and JavaScript. Not the best though, since the condition will evaluate for every document: $where
db.collection.find(function(){
return ( this.firstName + " " + this.lastName ) == "Peter Robert";
})
Probably works better with an aggregation framework:
db.collection.aggregate([
// Borrow something from above to get "might" match documents
{ "$match": {
"$or": [
{ "firstName": { "$regex": regexStr } },
{ "lastName": { "$regex": regexStr }}
]
}},
// Then project a "fullName"
{ "$project": {
"firstName": 1,
"lastName": 1,
"fullName": { "$concat": [ "$firstName", " ", "$lastName" ] }
}},
// Match on the fullName value
{ "$match": { "fullName": input } }
])
There are many ways to do this. You are not limited to frameworks (such as those that "emulate" Mongo functionality on the client), as there are multiple ways to handle this, and server side operations such as "text search" and aggregation and "JavaScript queries" can be executed in server-side logic code.
source to share