我有一个名为dummy的集合。它的模式定义为-
const schema = mongoose.Schema(
{
Name: { type: String },
start: { type: String },
end: { type: String },
}
字符串
现在我想从end < x
的集合中获取文档。但这里有一个问题-
1.从文档匹配上面的过滤器我不想要那些文档的Name
,我们可以找到另一个文档,其中start<=x<=end
。
1.对于每个Name
,只应该在end最接近x的地方获取一个文档。
我可以在多个聚合管道中实现这一点,方法是在第一个聚合管道中获取namesArr
中的所有Name
,其中start<=x<=end
,然后使用{$nin:namesArr}
删除具有这些名称的文档,然后按Name
分组,并以降序排序插入所有文档,并首先选择在第二个聚合管道中end最接近x的每个总线只获取一个文档。示例集合-
{Name : 'a', start :30, end :35},
{Name : 'a', start :40, end :50},
{Name : 'b', start :10, end :25},
{Name : 'b', start :30, end :35},
{Name : 'b', start :60, end :80},
型
所以如果x是44,那么查询应该只返回{Name : 'b', start :30, end :35}
但是我想在单个聚合管道中实现这一点,因为我不想首先获取namesArr,然后将其传递到第二个聚合管道中。
1条答案
按热度按时间v1l68za41#
我们可以通过计算4个辅助字段来实现所需的行为。
isInRange
:boolean,表示start<=x<=end
是否diffToX
:数字,表示x
和end
的绝对差值通过对Name
字段进行分组,我们得到了2个聚合的辅助字段anyInRange
:boolean,通过使用$max
,我们检查是否有任何isInRange
在Name
组中。如果任何条目在范围内,最终结果为true;否则为false。rank
:int,通过对diffToX
进行排序来计算排名。最接近X的条目应该具有最高的排名(即最小的排名数)通过使用4个辅助字段,我们可以在以下步骤中获得您期望的结果:
1.计算每个文档的
isInRange
和diffToX
1.使用
"partitionBy": "$Name"
和"sortBy": {"diffToX": 1}
在$setWindowFields
中计算anyInRange
和rank
$match
with end <= X and anyInRange:false$sort
,rank:1和$limit: 1
,以获得最接近X的条目字符串
Mongo Playground