Mongodb 按可能不存在的字段查询和排序mongo中的大量数据
我对mongo比较陌生,我有一个类似这样的收藏:Mongodb 按可能不存在的字段查询和排序mongo中的大量数据,mongodb,mongodb-query,projection,Mongodb,Mongodb Query,Projection,我对mongo比较陌生,我有一个类似这样的收藏: [ { "stored": { "box": [ { "parcelId": "uwb1", "status": "ACTIVE" } ] }, "checked": { "bo
[
{
"stored": {
"box": [
{
"parcelId": "uwb1",
"status": "ACTIVE"
}
]
},
"checked": {
"box": [
{
"parcelId": "uwb1",
"status": "ACTIVE"
}
]
}
},
{
"stored": {
"box": [
{
"parcelId": "aqrf123",
"status": "PENDING"
}
]
},
"checked": {
"box": [
{
"parcelId": "aqrf123",
"status": "PENDING"
}
]
}
},
{
"checked": {
"box": [
{
"parcelId": "zuz873",
"status": "ACTIVE"
}
]
}
}
]
db.getCollection('entries')
.aggregate([{
$addFields: {
sortStatus: {
$ifNull: [{
$let: {
vars: {
box: {
$arrayElemAt: [
"$stored.box", 0
]
}
},
in: "$$box.status"
}
}, {
$let: {
vars: {
box: {
$arrayElemAt: [
"$checked.box", 0
]
}
},
in: "$$box.status"
}
}]
}
}
},
{
$sort: {
sortStatus: 1
}
}
], {
allowDiskUse: true
})
关于数据的一些观察结果:
- 文档将始终选中
字段,但可能没有存储
字段
- 选中的
和存储的
字段具有相同的架构
- 两者都将始终有
字段,我们可以假设框
字段在数组中始终有1个元素(仅1个,不多,不少)框
- 此集合中的文档数量相对较高(约1亿)
状态
字段对文档进行排序,该字段类似于一个枚举,它可以有3个值-活动
,待定
和拒绝
- 如果文档中存在
字段,我将从那里获取它,并忽略存储的
字段李>选中的
- 否则,我将不得不从
字段中获取它,正如前面提到的,它保证存在checked
- 一个重要的要求是将整个文档返回给消费者/客户机,因此我不能使用
来减少文档中的数据量(这可能会使整个操作更快)projection
[
{
"stored": {
"box": [
{
"parcelId": "uwb1",
"status": "ACTIVE"
}
]
},
"checked": {
"box": [
{
"parcelId": "uwb1",
"status": "ACTIVE"
}
]
}
},
{
"stored": {
"box": [
{
"parcelId": "aqrf123",
"status": "PENDING"
}
]
},
"checked": {
"box": [
{
"parcelId": "aqrf123",
"status": "PENDING"
}
]
}
},
{
"checked": {
"box": [
{
"parcelId": "zuz873",
"status": "ACTIVE"
}
]
}
}
]
db.getCollection('entries')
.aggregate([{
$addFields: {
sortStatus: {
$ifNull: [{
$let: {
vars: {
box: {
$arrayElemAt: [
"$stored.box", 0
]
}
},
in: "$$box.status"
}
}, {
$let: {
vars: {
box: {
$arrayElemAt: [
"$checked.box", 0
]
}
},
in: "$$box.status"
}
}]
}
}
},
{
$sort: {
sortStatus: 1
}
}
], {
allowDiskUse: true
})
这看起来很有效,但感觉很慢。还有allowDiskUse
,这让我有点不舒服。如果我不使用它,我得到的排序超过了x字节的内存限制,但没有选择外部排序。正在中止操作。Pass allowDiskUse:选择加入时为true
错误消息
所以我的问题是:
allowDiskUse
选项是否存在任何风险.sort({“statusField”:1})
?这将是最后的选择,因为我必须迁移现有数据您的
sortStatus
字段值可以通过以下方式获得:
{ $addFields: { sortStatus: { $ifNull: [ "$stored.box.status", "$checked.box.status" ] } } },
这会使查询更快吗?没有,但是代码更简单
(1) 是否有更快的替代方案,无论是否有聚合 我不知道,此刻
(2) 在执行任务时使用allowDiskUse选项是否存在任何风险 聚合 使用
allowDiskUse:true
选项意味着当用于此操作的内存(RAM)超过其限制时,排序操作将使用磁盘获取额外资源。与内存相比,磁盘IO非常慢,因此“风险”是一个慢得多的排序操作。当排序操作需要的内存超过100MB限制时,此选项成为必需选项(请参阅上的文档)
(3) 改变一点是不是更好(或者是“mongo”方式) 文档结构,并将该可排序字段添加到 文档,为它添加一个索引,然后只使用.sort({“statusField”:1})? 这将是最后的选择,因为我必须迁移 现有数据 在该字段上创建新的状态字段和索引意味着新的注意事项:
- 创建新字段“status”需要在 编写文档的时间(也可能在更新期间)
- 在这个新字段上创建索引也是写入期间的额外开销。注意,由于文档数量较多,索引大小将较大
这是一些关于的文档。我明白了,谢谢你的详细回答。由于
allowDiskUse
而变慢并不是一个破坏交易的因素,我担心的是不会导致任何问题/致命错误。事实上,选项(3)似乎更令人头痛。