简体   繁体   English

将2个文本字段搜索为1个字段

[英]Search 2 text fields as 1 field

I'm to search users by name and I've the properties: firstName and lastName . 我要按名称搜索用户,我有属性: firstNamelastName If I had a property fullName this would be trivial but I don't have it. 如果我有一个属性fullName这将是微不足道的,但我没有。

I want to search for "Peter Robert" and I need to combine theses 2 fields into 1 before searching. 我想搜索“Peter Robert”,我需要在搜索之前将这两个字段合并为1。

How do I do it? 我该怎么做?

Sounds basically like you want a "text search" . 听起来基本上就像你想要一个“文本搜索” Text indexes can span over multiple fields so terms entered would be searched from all indexed fields: 文本索引可以跨越多个字段,因此将从所有索引字段中搜索输入的术语:

db.collection.ensureIndex({ "firstName": "text", "lastName": "text" })

db.collection.find({ "$text": { "$search": "Peter Robert" } })

That is one way to handle this. 这是解决这个问题的一种方法。 Will return other matches as well but exact matches have the highest score so you can rank them. 也将返回其他匹配,但完全匹配的得分最高,因此您可以对它们进行排名。

Alternately, if you know you are always getting a string like "Peter Robert" in that order then you can always "split" and tokenize the input: 或者,如果你知道你总是按顺序得到像“Peter Robert”这样的字符串,那么你总是可以“拆分”并标记输入:

var input = "Peter Robert";
var parts = input.split(/ /); // splits on space

db.collection.find({
    "firstName": parts[0],
    "lastName" parts[1]
])

Which is all pretty basic. 这一切都非常基础。 Or even apply the $regex and $or operators 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 this with the $where operator and JavaScript. 老实说,你甚至可以用$where运算符和JavaScript来做到这一点。 Not the best though since the condition would evaluate for every document: 不是最好的,因为条件会评估每个文档:

db.collection.find(function(){
    return ( this.firstName + " " + this.lastName ) == "Peter Robert";
})

Probably plays bit better with the aggregation framework though: 尽管如此,使用聚合框架可能会更好一些:

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 } }

])

Many ways to do this. 许多方法可以做到这一点。 You are not restricted by frameworks ( such as those that "emulate" Mongo functions on a client ) since there are both multiple ways to process this and server side operations like "text search" and aggregation and "JavaScript queries" can all be done in server logic code. 您不受框架的限制(例如那些“模拟”客户端上的Mongo函数的框架),因为有多种方法可以处理它,服务器端操作如“文本搜索”和聚合以及“JavaScript查询”都可以在服务器逻辑代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM