@@ -2,6 +2,7 @@ package topo
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"strings"
6
7
7
8
"go.mongodb.org/mongo-driver/bson"
@@ -153,18 +154,35 @@ func getShardMapImpl(ctx context.Context, m *mongo.Client) (map[ReplsetName]Shar
153
154
// if shard name is not set, mongodb will provide unique name for it
154
155
// (e.g. the replset name of the shard)
155
156
// for configsvr, key name is "config"
156
- var shardMap struct { Map map [string ]string }
157
+ // hosts field is used to discover hidden members, which are not present in map field
158
+ var shardMap struct {
159
+ Map map [string ]string
160
+ Hosts map [string ]string
161
+ }
157
162
if err := res .Decode (& shardMap ); err != nil {
158
163
return nil , errors .Wrap (err , "decode" )
159
164
}
160
165
166
+ // Example of the hosts field from command output:
167
+ // hosts: {
168
+ // 'rs103:27017': 'rs1',
169
+ // 'rs101:27017': 'rs1',
170
+ // 'cfg02:27017': 'config',
171
+ // ...
172
+ // }
173
+ // hostsByShard will contain even hidden RS members
174
+ hostsByShard := map [string ][]string {}
175
+ for host , shardID := range shardMap .Hosts {
176
+ hostsByShard [shardID ] = append (hostsByShard [shardID ], host )
177
+ }
178
+
161
179
shards := make (map [string ]Shard , len (shardMap .Map ))
162
180
for id , host := range shardMap .Map {
163
181
rs , _ , _ := strings .Cut (host , "/" )
164
182
shards [rs ] = Shard {
165
183
ID : id ,
166
184
RS : rs ,
167
- Host : host ,
185
+ Host : fmt . Sprintf ( "%s/%s" , rs , strings . Join ( hostsByShard [ id ], "," )) ,
168
186
}
169
187
}
170
188
0 commit comments