mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-12-25 02:01:13 +08:00
PMM-6256 Updated ExplainCmd for MongoDB (#459)
* PMM-6256 Updated ExplainCmd for MongoDB In order to make explain for MongoDB work, we need to remove the "$db" field from the explain command generated in proto.system.profile since it is a duplicated field that triggers a MongoDB error. * PMM-6256 New test * PMM-6256 Removed commented out code Co-authored-by: Carlos <cfsalguero@gmail.com>
This commit is contained in:
@@ -178,7 +178,6 @@ func (self ExampleQuery) ExplainCmd() bson.D {
|
||||
} else {
|
||||
cmd = append(cmd[:i], cmd[i+1:]...)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,6 +249,8 @@ func (self ExampleQuery) ExplainCmd() bson.D {
|
||||
}
|
||||
}
|
||||
case "command":
|
||||
cmd = sanitizeCommand(cmd)
|
||||
|
||||
if len(cmd) == 0 || cmd[0].Key != "group" {
|
||||
break
|
||||
}
|
||||
@@ -284,3 +285,28 @@ func (self ExampleQuery) ExplainCmd() bson.D {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func sanitizeCommand(cmd bson.D) bson.D {
|
||||
if len(cmd) < 1 {
|
||||
return cmd
|
||||
}
|
||||
|
||||
key := cmd[0].Key
|
||||
if key != "count" && key != "distinct" {
|
||||
return cmd
|
||||
}
|
||||
|
||||
for i := range cmd {
|
||||
// drop $db param as it is not supported in MongoDB 3.0
|
||||
if cmd[i].Key == "$db" {
|
||||
if len(cmd)-1 == i {
|
||||
cmd = cmd[:i]
|
||||
} else {
|
||||
cmd = append(cmd[:i], cmd[i+1:]...)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
44
src/go/mongolib/proto/system.profile_test.go
Normal file
44
src/go/mongolib/proto/system.profile_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package proto_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func TestExplainCmd(t *testing.T) {
|
||||
tests := []struct {
|
||||
inDoc []byte
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
inDoc: []byte(`{"ns":"sbtest.orders","op":"command","command":{"aggregate":"orders",` +
|
||||
`"pipeline":[{"$match":{"status":"A"}},{"$group":{"_id":"$cust_id","total":{"$sum":"$amount"}}},` +
|
||||
`{"$sort":{"total":-1}}],"cursor":{},"$db":"sbtest"}}`),
|
||||
want: []byte(`{"explain":{"aggregate":"orders","pipeline":[{"$match":{"status":"A"}},` +
|
||||
`{"$group":{"_id":"$cust_id","total":{"$sum":"$amount"}}},` +
|
||||
`{"$sort":{"total":-1}}],"cursor":{},"$db":"sbtest"}}`),
|
||||
},
|
||||
{
|
||||
inDoc: []byte(`{"ns":"sbtest.people","op":"command","command":` +
|
||||
`{"count":"people","query":{},"fields":{},"$db":"sbtest"}}`),
|
||||
want: []byte(`{"explain":{"count":"people","query":{},"fields":{}}}`),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
var want bson.D
|
||||
err := bson.UnmarshalExtJSON(tc.want, false, &want)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var doc proto.SystemProfile
|
||||
err = bson.UnmarshalExtJSON(tc.inDoc, false, &doc)
|
||||
assert.NoError(t, err)
|
||||
|
||||
eq := proto.NewExampleQuery(doc)
|
||||
|
||||
assert.Equal(t, want, eq.ExplainCmd())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user