MongoDB按相关性排序(混合$and和$or)
有两个文件,如:MongoDB按相关性排序(混合$and和$or),mongodb,sorting,mongodb-query,aggregation-framework,Mongodb,Sorting,Mongodb Query,Aggregation Framework,有两个文件,如: { "name": "hello", "family": 1 }, { "name": "world", "family": 1, "category": 2 } 还有一个查询,如: doc.find({$or: [{family: 1}, {category: 2}]}) 如何使结果与匹配2个条件的结果(“world”)排序作为第一个结果,而文档仅匹配1个条件作为最后一个结果(“hello”) 我不能使用默认的$and运算符,因为我
{
"name": "hello",
"family": 1
},
{
"name": "world",
"family": 1,
"category": 2
}
还有一个查询,如:
doc.find({$or: [{family: 1}, {category: 2}]})
如何使结果与匹配2个条件的结果(“world”)排序作为第一个结果,而文档仅匹配1个条件作为最后一个结果(“hello”)
我不能使用默认的$and运算符,因为我不会看到与这两个条件不匹配的“hello”文档
我看到了聚合是如何起作用的,但对于一个更复杂的例子来说,它需要大量的计算,我猜这是一个常见的用例,肯定有一些明显的地方我遗漏了你不能用一个简单的
.find()
语句来进行那种查询(双关语不是有意的)。您要求的是“加权”,即对值应用“计算出的优先级”
任何带有“计算”的内容基本上都是以编程方式应用的条件,这里用于“排序”的特定断言排除了“JavaScript运行程序”选项,如mapReduce
,只需离开聚合框架或其他结果处理
对于聚合框架方法,您需要根据以下条件计算每个匹配文档的“权重”:
db.collection.aggregate([
// Same match conditions to filter
{ "$match": { "$or": [{ "family": 1, }, { "category": 2 }] } },
// Assign the "weight" based on conditions
{ "$project": {
"name": 1,
"family": 1,
"weight": {
"$add": [
{ "$cond": {
"if": { "$eq": [ "$family", 1 ] },
"then": 1,
"else": 0
}},
{ "$cond": {
"if": { "$eq": [ "$category", 2 ] },
"then": 1,
"else": 0
}}
]
}
}},
// Then sort "descending" with highest "weight" on top
{ "$sort": { "weight": -1 } }
])
基本上,您是使用来评估返回的文档实际具有符合您条件的数据的条件,因为在选择中,存在的任何字段都是有效的响应。在存在条件的情况下,我们分配一个值,而在不存在条件的情况下,值为0
当“两个”条件都存在时,操作会将总重量合并到重量中。因此,此处仅满足一个条件的文档有一个1
,对于这两个条件,它们都有2
。例如,如果您想要“家族”“若要获得更大的偏好,则您将在条件中分配2
,留下可能的文档分数:
- 3:对于类别和系列
- 2:仅适用于家庭
- 1:仅适用于类别
除此之外,数据库服务不允许对“排序”进行“计算”。这被认为是“操纵”,这是聚合框架的目的 虽然您可以通过在客户机代码中对结果集进行后处理来进行相同类型的“加权”,但这里的问题当然是您希望“限制”结果在“分页”之类的操作中返回。这就是在服务器上运行操作的原因,也是使用聚合框架的原因