具有完全匹配优先级的Mongodb聚合匹配查询

具有完全匹配优先级的Mongodb聚合匹配查询,mongodb,mongodb-query,Mongodb,Mongodb Query,我正在尝试对字段执行mongodb正则表达式查询。如果查询找到一个完整匹配项,我希望该查询对其进行优先级排序,然后再对部分匹配项进行优先级排序 例如,如果我有一个数据库充满了以下条目 { "username": "patrick" }, { "username": "robert" }, { "username": "patrice" }, { "username": "pat" }, { "username": "patter" }, { "username

我正在尝试对字段执行mongodb正则表达式查询。如果查询找到一个完整匹配项,我希望该查询对其进行优先级排序,然后再对部分匹配项进行优先级排序

例如,如果我有一个数据库充满了以下条目

{
   "username": "patrick"
},
{
   "username": "robert"
},
{
   "username": "patrice"
},
{
   "username": "pat"
},
{
   "username": "patter"
},
{
   "username": "john_patrick"
}
我查询用户名“pat”,我想首先通过直接匹配返回结果,然后是部分匹配。因此,结果将按顺序排列['pat'、'patrick'、'patrice'、'patter'、'john_patrick']

单独使用mongo查询是否可以做到这一点?如果是这样的话,有人能告诉我一个资源,详细说明如何实现它吗

下面是我试图用来执行此操作的查询

db.accounts.aggregate({ $match : 
{ 
    $or : [ 
        { "usernameLowercase" : "pat" },
        { "usernameLowercase" : { $regex : "pat" } }
    ] 
} })

举一个精确的例子,这可以通过以下方式实现-如果您的真实世界场景稍微复杂一点,您可能会遇到问题,但是:

db.accounts.aggregate([{
    $match: {
        "username": /pat/i // find all documents that somehow match "pat" in a case-insensitive fashion
    }
}, {
    $addFields: {
        "exact": { 
            $eq: [ "$username", "pat" ] // add a field that indicates if a document matches exactly
        },
        "startswith": { 
            $eq: [ { $substr: [ "$username", 0, 3 ] }, "pat" ] // add a field that indicates if a document matches at the start
        }

    }
}, {
    $sort: {
        "exact": -1, // sort by our primary temporary field
        "startswith": -1 // sort by our seconday temporary
    }
}, {
    $project: {
        "exact": 0, // get rid of the "exact" field,
        "startswith": 0 // same for "startswith"
    }
}])
另一种方法是使用
$facet
,通过启用更复杂的场景,这可能会证明它的功能更强大,但速度会更慢(不过,对于这个提议,这里的一些人会讨厌我):


可能的复制品正是我想要的,非常感谢。
db.accounts.aggregate([{
    $facet: { // run two pipelines against all documents
        "exact": [{ // this one will capture all exact matches
            $match: {
                "username": "pat"
            }
        }],
        "others": [{ // this one will capture all others
            $match: {
                "username": { $ne: "pat", $regex: /pat/i }
            }
        }]
    }
}, {
    $project: {
        "result": { // merge the two arrays
            $concatArrays: [ "$exact", "$others" ]
        }
    }
}, {
    $unwind: "$result" // flatten the resulting array into separate documents
}, {
    $replaceRoot: { // restore the original document structure
        "newRoot": "$result"
    }
}])