Mongo db自定义搜索文本

时间:2018-02-22 05:45:15

标签: mongodb

{
name:"zpp test"
}
{
name:"test"
}
{
name:"test111"
}
{
name:"test surya"
}

现在我需要使用test关键字

进行搜索

我想要记录像

这样的记录

完全匹配

{
name:"test"
}
{
name:'test111'
}

{
name:"test surya"
}
{
name:"zpp test", 
}

优先级:

Exact match first

Next starts with

Next contains

我需要搜索多个文件。

2 个答案:

答案 0 :(得分:0)

您可以使用正则表达式进行此类搜索。

以下是搜索用户名和姓名的示例。

Users.find({ $or: [{ username: { $regex: new RegExp(query, 'ig') } }, { name: { $regex: new RegExp(query, 'ig') } }] }).exec((err, result) => {
//do something 
})

答案 1 :(得分:0)

您可以使用此聚合管道:

db.collection.aggregate({
    $addFields: {
        "priority": { // add new field called priority
            $switch: {
                "branches": [
                    { case: { $eq: [ "$name", "test" ] }, then: 1 }, // set priority to one for an exact match
                    { case: { $eq: [ { $substr: [ "$name", 0, 4 ] }, "test" ] }, then: 2 }, // set priority to 2 for a "starts with" match
                    { case: { $ne: [ { $indexOfBytes: [ "$name", "test" ] }, -1 ] }, then: 3 }, // set priority to 3 for a "contains" match
                ],
                default: null // set priority to null if no match
            }
        }
    }
}, {
    $match: { "priority": { $ne: null } } // filter out non-matching documents
}, {
    $sort: { "priority": 1 } // sort by priority
})

根据您的数据量和最终查询的复杂性,可能具有吸引力的替代方案可能就是这样。但请注意,这很可能会导致性能下降,因为我们会对所有文档进行三次有效评估:

db.collection.aggregate({
    $facet: { // create three separate aggregation pipelines
        "exact": [{ // one holding all documents...
            $match: { "name": "test" } // ...that are exactly matched
        }, {
            $addFields: { "priority": 1 } // ...and an additional field "priority": 1
        }],
        "startsWith": [{ // a 2nd one holding all documents...
            $match: { "name": /^test/ } // ...that match the "starts with" filter
        }, {
            $addFields: { "priority": 2 } // ...and an additional field "priority": 2
        }],
        "contains": [{ // a 3rd one holding all documents...
            $match: { "name": /test/ } // ...that match the "contains" filter
        }, {
            $addFields: { "priority": 3 } // ...and an additional field "priority": 3
        }]
    }
}, {
    $project: {
        "allResults": { // merge the results of the three pipelines
            $concatArrays: [ "$exact", "$startsWith", "$contains" ]
        }
    }
}, {
    $unwind: "$allResults" // and flatten the resulting array into individual documents
}, {
    $sort: { "allResults.priority": 1 } // sort all documents by priority
}, {
    $group: {
        "_id": "$allResults._id", // group by document id
        "result": { $first: "$$ROOT" } // and keep only the one with the highest priority
    }
}, {
    $replaceRoot: {
        newRoot: "$result.allResults" // restore the original document structure
    }
}, {
    $sort: { "priority": 1 } // and sort the results by "priority" again
})