【发布时间】:2020-12-22 04:56:10
【问题描述】:
上下文
我有一个 users 集合,其中包含一组键值对,如下所示:
{
name: 'David',
customFields: [
{ key: 'position', value: 'manager' },
{ key: 'department', value: 'HR' }
]
},
{
name: 'Allison',
customFields: [
{ key: 'position', value: 'employee' },
{ key: 'department', value: 'IT' }
]
}
customFields 中的字段名称可由应用程序用户配置,因此为了使其可索引,我将它们存储为键值对数组。索引{ 'customFields.key': 1, 'customFields.value': 1} 工作得很好。问题是当我想以任一顺序(升序或降序)检索结果时。假设我想按任意顺序对具有自定义字段 position 的所有用户进行排序。下面的查询给了我升序:
db.users.find({ customFields: { $elemMatch: { key: 'position' } } })
但是,我不知道如何得到相反的顺序。我很确定索引的结构方式,如果我可以告诉 mongodb 向后遍历索引,我会得到我想要的。另一种选择是使用另外 2 个索引来覆盖两个方向,但成本更高。
有没有办法指定遍历方向?如果没有,有什么好的选择?非常感谢。
编辑
我想进一步澄清我的情况。我试过了:
db.users.find({ customFields: { $elemMatch: { key: 'position' } } })
.sort({ 'customFields.key': 1, 'customFields.value': 1 })
db.users.find({ customFields: { $elemMatch: { key: 'position' } } })
.sort({'customFields.value': 1 })
这两个查询仅对过滤后的文档进行排序,这意味着排序将应用于它们拥有的所有自定义字段,而不是与查询匹配的字段(在本例中为position )。因此,使用sort 方法似乎没有任何帮助。
不使用任何排序可以方便地以正确的升序顺序返回文档。从解释结果中可以看出:
"direction" : "forward",
"indexBounds" : {
"customFields.key" : [
"[\"position\", \"position\"]"
],
"customFields.value" : [
"[MinKey, MaxKey]"
]
}
我对@987654331@ 使用完全匹配,所以我不在乎它的顺序。在customFields.key的每个值中,customFields.value的值都是按照索引中指定的顺序排列的,所以我就照原样取出来就好了。现在,如果我可以这样做:
db.users.find({ customFields: { $elemMatch: { key: 'position' } } })
.direction('backwards')
这相当于使用索引{ 'customFields.key': -1, 'customFields.value': -1 }。就像我说的,我不在乎customFields.key 的订单,而'customFields.value': -1 正是我想要的。我搜索了 mongodb 文档,但找不到类似的东西。
我可以检索与customFields.key 匹配的所有文档并自己进行排序,但它的成本很高,因为文档的数量可能会变得非常大。理想情况下,所有的过滤和排序都由索引来解决。
【问题讨论】:
-
你已按升序创建索引,按降序创建索引
{ 'customFields.key': -1, 'customFields.value': -1}