有两个文件,如:
{
"name": "hello",
"family": 1
},
{
"name": "world",
"family": 1,
"category": 2
}
和类似的查询:
doc.find({$or: [{family: 1}, {category: 2}]})
如何将结果与匹配2个条件(" world")作为第一个结果排序,但仍然只有1个条件作为最后结果匹配(" hello&# 34;)?
我不能使用默认的$和运算符,因为我不会看到"你好"文件不符合这两个条件。
我看到聚合如何有所帮助,但是对于一个更复杂的例子而不是大量的计算,我猜这是常见的用例,必须有一些明显的我缺失
答案 0 :(得分:1)
您不能使用简单的.find()
语句执行此类查询(双关语)。你要求的是"加权",它正在应用"计算优先级值。
任何"计算"基本上是以编程方式应用的条件,以及此处的特定断言" sort"排除" JavaScript跑步者"像mapReduce
这样的选项,只是让聚合框架或对结果进行其他处理。
对于聚合框架方法,您需要$project
计算出的"权重"根据条件对每个匹配的文档:
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 } }
])
基本上,您使用$cond
来评估返回的文档实际上具有满足您条件的数据的条件,因为在选择中,存在的字段是有效响应。如果条件存在,我们分配一个值,而值不是0
。
当"两者都是"条件存在$add
操作结合权重中的总和。因此,仅符合一个条件的文档只有1
,而且两者都有2
。如果你退缩了例如"家庭"要获得更大的偏好,那么您将在条件中分配2
,从而为您留下可能的文档分数:
您可以使用$project
管道运算符缩短MongoDB 3.4或更高版本中$addFields
的语法,这在您拥有" lot"您想要返回的其他文档属性,而无需在$project
中列出所有这些属性。
除此之外,数据库服务不允许在"排序"上进行"计算" 。这被认为是"操纵",这是聚合框架的目的。
虽然你可以做同样的"加权"通过在客户端代码中对结果集进行后期处理,这里的问题当然是您想要限制"在" paging"等行动中返回的结果。这是运行服务器上的操作的地方,以及为什么使用聚合框架的原因。