分片与非分片使用聚合的区别
$collStats
对于副本集中的集合或 集群中的非分片集合,collStats输出单个文档。对于分片集合,collStats每个分片输出一个文档。
count字段
计数基于集合的元数据,它为分片集群提供快速但有时不准确的计数。
非分片集合
使用语句:
use data;
db.datas.aggregate({
$collStats:{
count: {},
}}
)
输出结果:
{
"ns" : "data.datas",
"host" : "A:27017",
"localTime" : ISODate("2021-08-26T03:00:06.341+0000"),
"count" : NumberInt(16)
}
分片集合
使用语句:
use test2;
db.test21.aggregate({
$collStats:{
count: {},
}}
)
输出结果:
{
"ns" : "test2.test21",
"shard" : "rs0",
"host" : "A:27001",
"localTime" : ISODate("2021-08-26T02:59:18.063+0000"),
"count" : NumberInt(31268)
}
{
"ns" : "test2.test21",
"shard" : "rs2",
"host" : "A:27022",
"localTime" : ISODate("2021-08-26T02:59:18.063+0000"),
"count" : NumberInt(1)
}
{
"ns" : "test2.test21",
"shard" : "rs1",
"host" : "A:27012",
"localTime" : ISODate("2021-08-26T02:59:18.064+0000"),
"count" : NumberInt(28731)
}
$currentOp*
在启用了身份验证的独立集或副本集上,如果allUsers参数设置为 true,则需要inprog特权才能运行$currentOp。
在分片群集上,需要inprog特权才能运行所有$currentOp管道。
$graphLookup
from字段
from中指定的集合不能为sharded。但是,可以对运行aggregate()方法的集合进行分片。也就是说,在下面:
db.collection.aggregate([
{ $graphLookup: { from: "fromCollection", ... } }
])
- collection可以被分片。
- fromCollection无法分片。
要加入多个分片集合,请考虑:
- 修改 Client 端应用程序以执行手动查找,而不是使用$graphLookup聚合阶段。
- 如果可能,请使用嵌入式数据模型消除加入集合的需要。
$indexStats
shard输出字段
与主机关联的分片的名称
仅适用于分片集群。
非分片集合
使用语句:
use data;
db.datas.aggregate([
{ $indexStats: { } }
])
输出结果:
{
"name" : "_id_",
"key" : {
"_id" : NumberInt(1)
},
"host" : "A:27017",
"accesses" : {
"ops" : NumberLong(1),
"since" : ISODate("2021-08-26T02:09:10.509+0000")
},
"spec" : {
"v" : NumberInt(2),
"key" : {
"_id" : NumberInt(1)
},
"name" : "_id_"
}
}
……
分片集合
使用语句:
use test2;
db.test21.aggregate([
{ $indexStats: { } }
])
输出结果:
{
"name" : "_id_",
"key" : {
"_id" : NumberInt(1)
},
"host" : "A:27001",
"accesses" : {
"ops" : NumberLong(1),
"since" : ISODate("2021-08-26T02:06:27.765+0000")
},
"shard" : "rs0",
"spec" : {
"v" : NumberInt(2),
"key" : {
"_id" : NumberInt(1)
},
"name" : "_id_"
}
}
……
$lookup
对同一数据库中的未分片集合执行左外部联接,以从“被联接”集合中过滤文档以进行处理。
from字段
指定在同一数据库中执行连接的集合。该from集合不能被分片。
在$lookup阶段,from集合不能被分片。但是可以对运行该aggregate()方法的集合进行分片。具体来说,在这个例子中:
db.collection.aggregate([
{ $lookup: { from: "fromCollection", ... } }
])
- 该collection可以分片。
- 在fromCollection不能分片。
要将分片集合与未分片集合连接,请在分片集合上运行聚合并查找未分片集合。例如:
db.shardedCollection.aggregate([
{ $lookup: { from: "unshardedCollection", ... } }
])
或者,或者要加入多个分片集合,请考虑:
- 修改客户端应用程序以执行手动查找而不是使用$lookup聚合阶段。
- 如果可能,请使用无需加入集合的嵌入式数据模型。
- 如果可能,使用Atlas Data Lake $lookup 管道阶段来查找分片集合。
如果from集合为分片集合,则会显示:
{
"ok" : 0.0,
"errmsg" : "test2.inventory cannot be sharded",
"code" : 28769.0,
"codeName" : "Location28769",
"operationTime" : Timestamp(1629959728, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1629959728, 1),
"signature" : {
"hash" : BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : 0.0
}
}
}
$merge
into字段
- 如果输出集合不存在,则$merge 创建集合:
- 对于副本集或独立的,如果输出数据库不存在,$merge 也会创建数据库。
- 对于分片cluster,指定的输出数据库必须已经存在。
- 输出集合可以是分片集合。
on字段
- 如果现有输出集合未分片,则on 标识符默认为该_id字段。
- 如果现有输出集合是分片集合,则 on标识符默认为所有分片键字段和_id字段。如果指定不同的 on标识符,则on必须包含所有分片键字段。
whenMatched字段
"replace"操作:执行replace时,替换文档不能导致_id值的修改,或者如果输出集合是分片的,则不能修改分片键值。否则,操作会产生错误。
"merge" (默认)操作:执行merge时,合并的文档不能导致_id值的修改,或者如果输出集合是分片的,则不能修改分片键值。否则,操作会产生错误。
输出到分片集合
merge采用_id字段和所有的分片键字段作为默认的on标识符。如果重写默认值,则on标识符必须包含所有分片键字段。
$out
db字段
- 对于副本集或独立的,如果输出数据库不存在,$out也会创建数据库。
- 对于分片cluster,指定的输出数据库必须已经存在。
您不能将分片集合指定为输出集合。管道的输入集合可以分片。要输出到分片集合,请参阅$merge (从 MongoDB 4.2 开始可用)。
$planCacheStats
$planCacheStats在副本集上,该操作仅从副本集的一个成员收集计划缓存信息,而在分片集群上,该操作仅从每个分片副本集的一个成员收集计划缓存信息。
host输出字段
在分片集群上运行时,该操作从每个分片副本集中的单个成员返回计划缓存条目信息。该成员由shard和host 字段标识。
shard输出字段
从中$planCacheStats 检索缓存条目的分片的名称。
仅在分片集群上运行时可用。
$sort
当您在分片集群上使用$sort时,每个分片都使用可用的索引对其结果文档进行排序。然后分片 mongos或分片之一执行流式归并排序。
$unionWith
如果lookup pipeline的一部分,则$unionWith的coll集合不能是分片集合。