mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-15 07:55:51 +00:00
PMM-685: explain
This commit is contained in:
22
.travis.yml
22
.travis.yml
@@ -5,7 +5,21 @@ language: go
|
||||
|
||||
go:
|
||||
- 1.8.x
|
||||
- tip
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- MONGODB_IMAGE=mongo:3.2
|
||||
- MONGODB_IMAGE=mongo:3.4
|
||||
- MONGODB_IMAGE=percona/percona-server-mongodb:3.2
|
||||
- MONGODB_IMAGE=percona/percona-server-mongodb:3.4
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: tip
|
||||
env:
|
||||
|
||||
install:
|
||||
- go get -u github.com/Masterminds/glide
|
||||
@@ -16,6 +30,12 @@ install:
|
||||
before_script:
|
||||
# check if vendor dir is correct
|
||||
- git diff --exit-code
|
||||
# run docker containers
|
||||
- docker-compose up -d
|
||||
# log versions
|
||||
- docker --version
|
||||
- docker-compose --version
|
||||
- docker-compose exec mongo mongo --version
|
||||
|
||||
script:
|
||||
- go test -timeout 1m $(glide nv)
|
||||
|
@@ -5,9 +5,8 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
32
src/go/mongolib/explain/explain.go
Normal file
32
src/go/mongolib/explain/explain.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package explain
|
||||
|
||||
import (
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
||||
"github.com/percona/pmgo"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
type explain struct {
|
||||
session pmgo.SessionManager
|
||||
}
|
||||
|
||||
func New(session pmgo.SessionManager) *explain {
|
||||
return &explain{
|
||||
session: session,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *explain) Explain(eq proto.ExampleQuery) ([]byte, error) {
|
||||
var result proto.BsonD
|
||||
err := e.session.DB(eq.Db()).Run(eq.ExplainCmd(), &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resultJson, err := bson.MarshalJSON(result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resultJson, nil
|
||||
}
|
159
src/go/mongolib/explain/explain_test.go
Normal file
159
src/go/mongolib/explain/explain_test.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package explain
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/percona/percona-toolkit/src/go/lib/tutil"
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
||||
"github.com/percona/pmgo"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
const (
|
||||
samples = "/src/go/tests/"
|
||||
)
|
||||
|
||||
type testVars struct {
|
||||
RootPath string
|
||||
}
|
||||
|
||||
var vars testVars
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
var err error
|
||||
if vars.RootPath, err = tutil.RootPath(); err != nil {
|
||||
log.Printf("cannot get root path: %s", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestExplain(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dir := vars.RootPath + samples + "/doc/out/"
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot list samples: %s", err)
|
||||
}
|
||||
|
||||
expectError := map[string]string{
|
||||
"aggregate_2.6.12": "Cannot explain cmd: aggregate",
|
||||
"aggregate_3.0.15": "Cannot explain cmd: aggregate",
|
||||
"aggregate_3.2.16": "Cannot explain cmd: aggregate",
|
||||
"aggregate_3.4.7": "Cannot explain cmd: aggregate",
|
||||
"aggregate_3.5.11": "Cannot explain cmd: aggregate",
|
||||
"count_2.6.12": "<nil>",
|
||||
"count_3.0.15": "<nil>",
|
||||
"count_3.2.16": "<nil>",
|
||||
"count_3.4.7": "<nil>",
|
||||
"count_3.5.11": "<nil>",
|
||||
"count_with_query_2.6.12": "<nil>",
|
||||
"count_with_query_3.0.15": "<nil>",
|
||||
"count_with_query_3.2.16": "<nil>",
|
||||
"count_with_query_3.4.7": "<nil>",
|
||||
"count_with_query_3.5.11": "<nil>",
|
||||
"delete_2.6.12": "<nil>",
|
||||
"delete_3.0.15": "<nil>",
|
||||
"delete_3.2.16": "<nil>",
|
||||
"delete_3.4.7": "<nil>",
|
||||
"delete_3.5.11": "<nil>",
|
||||
"delete_all_2.6.12": "<nil>",
|
||||
"delete_all_3.0.15": "<nil>",
|
||||
"delete_all_3.2.16": "<nil>",
|
||||
"delete_all_3.4.7": "<nil>",
|
||||
"delete_all_3.5.11": "<nil>",
|
||||
"distinct_2.6.12": "<nil>",
|
||||
"distinct_3.0.15": "<nil>",
|
||||
"distinct_3.2.16": "<nil>",
|
||||
"distinct_3.4.7": "<nil>",
|
||||
"distinct_3.5.11": "<nil>",
|
||||
"find_empty_2.6.12": "<nil>",
|
||||
"find_empty_3.0.15": "<nil>",
|
||||
"find_empty_3.2.16": "<nil>",
|
||||
"find_empty_3.4.7": "<nil>",
|
||||
"find_empty_3.5.11": "<nil>",
|
||||
"find_2.6.12": "<nil>",
|
||||
"find_3.0.15": "<nil>",
|
||||
"find_3.2.16": "<nil>",
|
||||
"find_3.4.7": "<nil>",
|
||||
"find_3.5.11": "<nil>",
|
||||
"find_andrii_2.6.12": "<nil>",
|
||||
"find_andrii_3.0.15": "<nil>",
|
||||
"find_andrii_3.2.16": "<nil>",
|
||||
"find_andrii_3.4.7": "<nil>",
|
||||
"find_andrii_3.5.11": "<nil>",
|
||||
"findandmodify_2.6.12": "<nil>",
|
||||
"findandmodify_3.0.15": "<nil>",
|
||||
"findandmodify_3.2.16": "<nil>",
|
||||
"findandmodify_3.4.7": "<nil>",
|
||||
"findandmodify_3.5.11": "<nil>",
|
||||
"geonear_2.6.12": "Cannot explain cmd: geoNear",
|
||||
"geonear_3.0.15": "Cannot explain cmd: geoNear",
|
||||
"geonear_3.2.16": "Cannot explain cmd: geoNear",
|
||||
"geonear_3.4.7": "Cannot explain cmd: geoNear",
|
||||
"geonear_3.5.11": "Cannot explain cmd: geoNear",
|
||||
"group_2.6.12": "<nil>",
|
||||
"group_3.0.15": "<nil>",
|
||||
"group_3.2.16": "<nil>",
|
||||
"group_3.4.7": "<nil>",
|
||||
"group_3.5.11": "<nil>",
|
||||
"insert_2.6.12": "Cannot explain cmd: insert",
|
||||
"insert_3.0.15": "Cannot explain cmd: insert",
|
||||
"insert_3.2.16": "Cannot explain cmd: insert",
|
||||
"insert_3.4.7": "Cannot explain cmd: insert",
|
||||
"insert_3.5.11": "Cannot explain cmd: insert",
|
||||
"mapreduce_2.6.12": "Cannot explain cmd: mapReduce",
|
||||
"mapreduce_3.0.15": "Cannot explain cmd: mapReduce",
|
||||
"mapreduce_3.2.16": "Cannot explain cmd: mapReduce",
|
||||
"mapreduce_3.4.7": "Cannot explain cmd: mapReduce",
|
||||
"mapreduce_3.5.11": "Cannot explain cmd: mapReduce",
|
||||
"update_2.6.12": "<nil>",
|
||||
"update_3.0.15": "<nil>",
|
||||
"update_3.2.16": "<nil>",
|
||||
"update_3.4.7": "<nil>",
|
||||
"update_3.5.11": "<nil>",
|
||||
}
|
||||
|
||||
dialer := pmgo.NewDialer()
|
||||
dialInfo, err := pmgo.ParseURL("127.0.0.1:27017")
|
||||
require.NoError(t, err)
|
||||
|
||||
session, err := dialer.DialWithInfo(dialInfo)
|
||||
require.NoError(t, err)
|
||||
defer session.Close()
|
||||
|
||||
ex := New(session)
|
||||
|
||||
for _, file := range files {
|
||||
t.Run(file.Name(), func(t *testing.T) {
|
||||
eq := proto.ExampleQuery{}
|
||||
err := tutil.LoadBson(dir+file.Name(), &eq)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load sample %s: %s", dir+file.Name(), err)
|
||||
}
|
||||
got, err := ex.Explain(eq)
|
||||
expectErrMsg := expectError[file.Name()]
|
||||
gotErrMsg := fmt.Sprintf("%v", err)
|
||||
if gotErrMsg != expectErrMsg {
|
||||
t.Fatalf("explain error should be '%s' but was '%s'", expectErrMsg, gotErrMsg)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result := proto.BsonD{}
|
||||
err = bson.UnmarshalJSON(got, &result)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot unmarshal json explain result: %s", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -103,6 +103,11 @@ func TestFingerprints(t *testing.T) {
|
||||
"delete_3.2.16": "REMOVE coll a,b",
|
||||
"delete_3.4.7": "REMOVE coll a,b",
|
||||
"delete_3.5.11": "REMOVE coll a,b",
|
||||
"delete_all_2.6.12": "REMOVE coll a,b",
|
||||
"delete_all_3.0.15": "REMOVE coll a,b",
|
||||
"delete_all_3.2.16": "REMOVE coll a,b",
|
||||
"delete_all_3.4.7": "REMOVE coll a,b",
|
||||
"delete_all_3.5.11": "REMOVE coll a,b",
|
||||
"distinct_2.6.12": "DISTINCT coll a,b",
|
||||
"distinct_3.0.15": "DISTINCT coll a,b",
|
||||
"distinct_3.2.16": "DISTINCT coll a,b",
|
||||
|
@@ -73,7 +73,7 @@ func TestRegularIterator(t *testing.T) {
|
||||
ID: "16196765fb4c14edb91efdbe4f5c5973",
|
||||
Namespace: "samples.col1",
|
||||
Operation: "query",
|
||||
Query: "{\n \"find\": \"col1\",\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
Query: "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
Fingerprint: "FIND col1 find",
|
||||
FirstSeen: firstSeen,
|
||||
LastSeen: lastSeen,
|
||||
@@ -130,7 +130,7 @@ func TestIteratorTimeout(t *testing.T) {
|
||||
ID: "16196765fb4c14edb91efdbe4f5c5973",
|
||||
Namespace: "samples.col1",
|
||||
Operation: "query",
|
||||
Query: "{\n \"find\": \"col1\",\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
Query: "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
Fingerprint: "FIND col1 find",
|
||||
FirstSeen: firstSeen,
|
||||
LastSeen: lastSeen,
|
||||
@@ -211,7 +211,7 @@ func TestTailIterator(t *testing.T) {
|
||||
ID: "16196765fb4c14edb91efdbe4f5c5973",
|
||||
Namespace: "samples.col1",
|
||||
Operation: "query",
|
||||
Query: "{\n \"find\": \"col1\",\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
Query: "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
Fingerprint: "FIND col1 find",
|
||||
FirstSeen: parseDate("2017-04-01T23:01:20.214+00:00"),
|
||||
LastSeen: parseDate("2017-04-01T23:01:20.214+00:00"),
|
||||
@@ -226,7 +226,7 @@ func TestTailIterator(t *testing.T) {
|
||||
ID: "16196765fb4c14edb91efdbe4f5c5973",
|
||||
Namespace: "samples.col1",
|
||||
Operation: "query",
|
||||
Query: "{\n \"find\": \"col1\",\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
Query: "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
Fingerprint: "FIND col1 find",
|
||||
FirstSeen: parseDate("2017-04-01T23:01:19.914+00:00"),
|
||||
LastSeen: parseDate("2017-04-01T23:01:19.914+00:00"),
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
@@ -97,18 +98,32 @@ func (d BsonD) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
// marshal key
|
||||
key, err := json.Marshal(v.Name)
|
||||
key, err := bson.MarshalJSON(v.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.Write(key)
|
||||
b.WriteByte(':')
|
||||
|
||||
var val []byte
|
||||
if value, ok := v.Value.(float64); ok && math.IsInf(value, 0) {
|
||||
if math.IsInf(value, 1) {
|
||||
val = []byte("Infinity")
|
||||
} else {
|
||||
val = []byte("-Infinity")
|
||||
}
|
||||
|
||||
// below is wrong, but I'm later unable to Unmarshal Infinity,
|
||||
// so we turn it into string for now
|
||||
val = append([]byte(`"`), val...)
|
||||
val = append(val, '"')
|
||||
} else {
|
||||
// marshal value
|
||||
val, err := json.Marshal(v.Value)
|
||||
val, err = bson.MarshalJSON(v.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
b.Write(val)
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,10 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
type SystemProfile struct {
|
||||
@@ -74,9 +77,148 @@ type SystemProfile struct {
|
||||
Op string `bson:"op"`
|
||||
Protocol string `bson:"protocol"`
|
||||
Query BsonD `bson:"query"`
|
||||
UpdateObj BsonD `bson:"updateobj"`
|
||||
Command BsonD `bson:"command"`
|
||||
ResponseLength int `bson:"responseLength"`
|
||||
Ts time.Time `bson:"ts"`
|
||||
User string `bson:"user"`
|
||||
WriteConflicts int `bson:"writeConflicts"`
|
||||
}
|
||||
|
||||
func NewExampleQuery(doc SystemProfile) ExampleQuery {
|
||||
return ExampleQuery{
|
||||
Ns: doc.Ns,
|
||||
Op: doc.Op,
|
||||
Query: doc.Query,
|
||||
Command: doc.Command,
|
||||
UpdateObj: doc.UpdateObj,
|
||||
}
|
||||
}
|
||||
|
||||
// ExampleQuery is a subset of SystemProfile
|
||||
type ExampleQuery struct {
|
||||
Ns string `bson:"ns" json:"ns"`
|
||||
Op string `bson:"op" json:"op"`
|
||||
Query BsonD `bson:"query,omitempty" json:"query,omitempty"`
|
||||
Command BsonD `bson:"command,omitempty" json:"command,omitempty"`
|
||||
UpdateObj BsonD `bson:"updateobj,omitempty" json:"updateobj,omitempty"`
|
||||
}
|
||||
|
||||
func (self ExampleQuery) Db() string {
|
||||
ns := strings.SplitN(self.Ns, ".", 2)
|
||||
if len(ns) > 0 {
|
||||
return ns[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self ExampleQuery) ExplainCmd() bson.D {
|
||||
cmd := self.Command
|
||||
|
||||
switch self.Op {
|
||||
case "query":
|
||||
if cmd.Len() == 0 {
|
||||
cmd = self.Query
|
||||
}
|
||||
if cmd.Len() == 0 || cmd[0].Name != "find" {
|
||||
var filter interface{}
|
||||
if cmd.Len() > 0 && cmd[0].Name == "query" {
|
||||
filter = cmd[0].Value
|
||||
} else {
|
||||
filter = cmd
|
||||
}
|
||||
|
||||
coll := ""
|
||||
s := strings.SplitN(self.Ns, ".", 2)
|
||||
if len(s) == 2 {
|
||||
coll = s[1]
|
||||
}
|
||||
|
||||
cmd = BsonD{
|
||||
{"find", coll},
|
||||
{"filter", filter},
|
||||
}
|
||||
}
|
||||
case "update":
|
||||
s := strings.SplitN(self.Ns, ".", 2)
|
||||
coll := ""
|
||||
if len(s) == 2 {
|
||||
coll = s[1]
|
||||
}
|
||||
if cmd.Len() == 0 {
|
||||
cmd = BsonD{
|
||||
{Name: "q", Value: self.Query},
|
||||
{Name: "u", Value: self.UpdateObj},
|
||||
}
|
||||
}
|
||||
cmd = BsonD{
|
||||
{Name: "update", Value: coll},
|
||||
{Name: "updates", Value: []interface{}{cmd}},
|
||||
}
|
||||
case "remove":
|
||||
s := strings.SplitN(self.Ns, ".", 2)
|
||||
coll := ""
|
||||
if len(s) == 2 {
|
||||
coll = s[1]
|
||||
}
|
||||
if cmd.Len() == 0 {
|
||||
cmd = BsonD{
|
||||
{Name: "q", Value: self.Query},
|
||||
// we can't determine if limit was 1 or 0 so we assume 0
|
||||
{Name: "limit", Value: 0},
|
||||
}
|
||||
}
|
||||
cmd = BsonD{
|
||||
{Name: "delete", Value: coll},
|
||||
{Name: "deletes", Value: []interface{}{cmd}},
|
||||
}
|
||||
case "insert":
|
||||
if cmd.Len() == 0 {
|
||||
cmd = self.Query
|
||||
}
|
||||
if cmd.Len() == 0 || cmd[0].Name != "insert" {
|
||||
coll := ""
|
||||
s := strings.SplitN(self.Ns, ".", 2)
|
||||
if len(s) == 2 {
|
||||
coll = s[1]
|
||||
}
|
||||
|
||||
cmd = BsonD{
|
||||
{"insert", coll},
|
||||
}
|
||||
}
|
||||
case "command":
|
||||
if cmd.Len() == 0 || cmd[0].Name != "group" {
|
||||
break
|
||||
}
|
||||
|
||||
if v, ok := cmd[0].Value.(BsonD); ok {
|
||||
for i := range v {
|
||||
// for MongoDB <= 3.2
|
||||
// "$reduce" : function () {}
|
||||
// It is then Unmarshaled as empty value, so in essence not working
|
||||
//
|
||||
// for MongoDB >= 3.4
|
||||
// "$reduce" : {
|
||||
// "code" : "function () {}"
|
||||
// }
|
||||
// It is then properly Unmarshaled but then explain fails with "not code"
|
||||
//
|
||||
// The $reduce function shouldn't affect explain execution plan (e.g. what indexes are picked)
|
||||
// so we ignore it for now until we find better way to handle this issue
|
||||
if v[i].Name == "$reduce" {
|
||||
v[i].Value = ""
|
||||
cmd[0].Value = v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bson.D{
|
||||
{
|
||||
Name: "explain",
|
||||
Value: cmd,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -6,11 +6,11 @@ import (
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/montanaflynn/stats"
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/fingerprinter"
|
||||
"github.com/percona/percona-toolkit/src/go/mongolib/proto"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
type StatsError struct {
|
||||
@@ -30,7 +30,6 @@ func (e *StatsError) Parent() error {
|
||||
}
|
||||
|
||||
type StatsFingerprintError StatsError
|
||||
type StatsGetQueryFieldError StatsError
|
||||
|
||||
// New creates new instance of stats with given fingerprinter
|
||||
func New(fingerprinter fingerprinter.Fingerprinter) *Stats {
|
||||
@@ -75,14 +74,8 @@ func (s *Stats) Add(doc proto.SystemProfile) error {
|
||||
Namespace: doc.Ns,
|
||||
}
|
||||
if qiac, ok = s.getQueryInfoAndCounters(key); !ok {
|
||||
query := doc.Query
|
||||
if doc.Command.Len() > 0 {
|
||||
query = doc.Command
|
||||
}
|
||||
if err != nil {
|
||||
return &StatsGetQueryFieldError{err}
|
||||
}
|
||||
queryBson, err := json.MarshalIndent(query, "", " ")
|
||||
query := proto.NewExampleQuery(doc)
|
||||
queryBson, err := bson.MarshalJSON(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -142,7 +142,7 @@ func TestStats(t *testing.T) {
|
||||
ID: "4e4774ad26f934a193757002a991ebb8",
|
||||
Namespace: "samples.col1",
|
||||
Operation: "query",
|
||||
Query: "{\n \"find\": \"col1\",\n \"filter\": {\n \"s2\": {\n \"$gte\": \"41991\",\n \"$lt\": \"33754\"\n }\n },\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
Query: "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"filter\":{\"s2\":{\"$gte\":\"41991\",\"$lt\":\"33754\"}},\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
Fingerprint: "FIND col1 s2",
|
||||
FirstSeen: parseDate("2017-04-10T13:15:53.532-03:00"),
|
||||
LastSeen: parseDate("2017-04-10T13:15:53.532-03:00"),
|
||||
|
33
src/go/tests/doc/out/delete_all_2.6.12
Normal file
33
src/go/tests/doc/out/delete_all_2.6.12
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"op" : "remove",
|
||||
"ns" : "test.coll",
|
||||
"query" : {
|
||||
"a" : {
|
||||
"$gte" : 2
|
||||
},
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"ndeleted" : 15,
|
||||
"keyUpdates" : 0,
|
||||
"numYield" : 0,
|
||||
"lockStats" : {
|
||||
"timeLockedMicros" : {
|
||||
"r" : NumberLong(0),
|
||||
"w" : NumberLong(238)
|
||||
},
|
||||
"timeAcquiringMicros" : {
|
||||
"r" : NumberLong(0),
|
||||
"w" : NumberLong(4)
|
||||
}
|
||||
},
|
||||
"millis" : 0,
|
||||
"execStats" : {
|
||||
|
||||
},
|
||||
"ts" : ISODate("2017-08-30T10:54:45.348Z"),
|
||||
"client" : "127.0.0.1",
|
||||
"allUsers" : [ ],
|
||||
"user" : ""
|
||||
}
|
47
src/go/tests/doc/out/delete_all_3.0.15
Normal file
47
src/go/tests/doc/out/delete_all_3.0.15
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"op" : "remove",
|
||||
"ns" : "test.coll",
|
||||
"query" : {
|
||||
"a" : {
|
||||
"$gte" : 2
|
||||
},
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"ndeleted" : 15,
|
||||
"keyUpdates" : 0,
|
||||
"writeConflicts" : 0,
|
||||
"numYield" : 0,
|
||||
"locks" : {
|
||||
"Global" : {
|
||||
"acquireCount" : {
|
||||
"r" : NumberLong(1),
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"MMAPV1Journal" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(16)
|
||||
}
|
||||
},
|
||||
"Database" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Collection" : {
|
||||
"acquireCount" : {
|
||||
"W" : NumberLong(1)
|
||||
}
|
||||
}
|
||||
},
|
||||
"millis" : 1,
|
||||
"execStats" : {
|
||||
|
||||
},
|
||||
"ts" : ISODate("2017-08-30T10:54:52.821Z"),
|
||||
"client" : "127.0.0.1",
|
||||
"allUsers" : [ ],
|
||||
"user" : ""
|
||||
}
|
42
src/go/tests/doc/out/delete_all_3.2.16
Normal file
42
src/go/tests/doc/out/delete_all_3.2.16
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"op" : "remove",
|
||||
"ns" : "test.coll",
|
||||
"query" : {
|
||||
"a" : {
|
||||
"$gte" : 2
|
||||
},
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"ndeleted" : 15,
|
||||
"keyUpdates" : 0,
|
||||
"writeConflicts" : 0,
|
||||
"numYield" : 0,
|
||||
"locks" : {
|
||||
"Global" : {
|
||||
"acquireCount" : {
|
||||
"r" : NumberLong(1),
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Database" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Collection" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
}
|
||||
},
|
||||
"millis" : 0,
|
||||
"execStats" : {
|
||||
|
||||
},
|
||||
"ts" : ISODate("2017-08-30T10:55:02.238Z"),
|
||||
"client" : "127.0.0.1",
|
||||
"allUsers" : [ ],
|
||||
"user" : ""
|
||||
}
|
113
src/go/tests/doc/out/delete_all_3.4.7
Normal file
113
src/go/tests/doc/out/delete_all_3.4.7
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"op" : "remove",
|
||||
"ns" : "test.coll",
|
||||
"query" : {
|
||||
"a" : {
|
||||
"$gte" : 2
|
||||
},
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"keysExamined" : 39,
|
||||
"docsExamined" : 39,
|
||||
"ndeleted" : 15,
|
||||
"keysDeleted" : 30,
|
||||
"numYield" : 0,
|
||||
"locks" : {
|
||||
"Global" : {
|
||||
"acquireCount" : {
|
||||
"r" : NumberLong(1),
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Database" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Collection" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
}
|
||||
},
|
||||
"millis" : 0,
|
||||
"planSummary" : "IXSCAN { a: 1 }",
|
||||
"execStats" : {
|
||||
"stage" : "DELETE",
|
||||
"nReturned" : 0,
|
||||
"executionTimeMillisEstimate" : 0,
|
||||
"works" : 40,
|
||||
"advanced" : 0,
|
||||
"needTime" : 39,
|
||||
"needYield" : 0,
|
||||
"saveState" : 0,
|
||||
"restoreState" : 0,
|
||||
"isEOF" : 1,
|
||||
"invalidates" : 0,
|
||||
"nWouldDelete" : 15,
|
||||
"nInvalidateSkips" : 0,
|
||||
"inputStage" : {
|
||||
"stage" : "FETCH",
|
||||
"filter" : {
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"nReturned" : 15,
|
||||
"executionTimeMillisEstimate" : 0,
|
||||
"works" : 40,
|
||||
"advanced" : 15,
|
||||
"needTime" : 24,
|
||||
"needYield" : 0,
|
||||
"saveState" : 15,
|
||||
"restoreState" : 15,
|
||||
"isEOF" : 1,
|
||||
"invalidates" : 0,
|
||||
"docsExamined" : 39,
|
||||
"alreadyHasObj" : 0,
|
||||
"inputStage" : {
|
||||
"stage" : "IXSCAN",
|
||||
"nReturned" : 39,
|
||||
"executionTimeMillisEstimate" : 0,
|
||||
"works" : 40,
|
||||
"advanced" : 39,
|
||||
"needTime" : 0,
|
||||
"needYield" : 0,
|
||||
"saveState" : 15,
|
||||
"restoreState" : 15,
|
||||
"isEOF" : 1,
|
||||
"invalidates" : 0,
|
||||
"keyPattern" : {
|
||||
"a" : 1
|
||||
},
|
||||
"indexName" : "a_1",
|
||||
"isMultiKey" : false,
|
||||
"multiKeyPaths" : {
|
||||
"a" : [ ]
|
||||
},
|
||||
"isUnique" : false,
|
||||
"isSparse" : false,
|
||||
"isPartial" : false,
|
||||
"indexVersion" : 2,
|
||||
"direction" : "forward",
|
||||
"indexBounds" : {
|
||||
"a" : [
|
||||
"[2.0, inf.0]"
|
||||
]
|
||||
},
|
||||
"keysExamined" : 39,
|
||||
"seeks" : 1,
|
||||
"dupsTested" : 0,
|
||||
"dupsDropped" : 0,
|
||||
"seenInvalidated" : 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"ts" : ISODate("2017-08-30T10:55:09.833Z"),
|
||||
"client" : "127.0.0.1",
|
||||
"appName" : "MongoDB Shell",
|
||||
"allUsers" : [ ],
|
||||
"user" : ""
|
||||
}
|
116
src/go/tests/doc/out/delete_all_3.5.11
Normal file
116
src/go/tests/doc/out/delete_all_3.5.11
Normal file
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"op" : "remove",
|
||||
"ns" : "test.coll",
|
||||
"command" : {
|
||||
"q" : {
|
||||
"a" : {
|
||||
"$gte" : 2
|
||||
},
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"limit" : 0
|
||||
},
|
||||
"keysExamined" : 39,
|
||||
"docsExamined" : 39,
|
||||
"ndeleted" : 15,
|
||||
"keysDeleted" : 30,
|
||||
"numYield" : 0,
|
||||
"locks" : {
|
||||
"Global" : {
|
||||
"acquireCount" : {
|
||||
"r" : NumberLong(1),
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Database" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
},
|
||||
"Collection" : {
|
||||
"acquireCount" : {
|
||||
"w" : NumberLong(1)
|
||||
}
|
||||
}
|
||||
},
|
||||
"millis" : 0,
|
||||
"planSummary" : "IXSCAN { a: 1 }",
|
||||
"execStats" : {
|
||||
"stage" : "DELETE",
|
||||
"nReturned" : 0,
|
||||
"executionTimeMillisEstimate" : 0,
|
||||
"works" : 40,
|
||||
"advanced" : 0,
|
||||
"needTime" : 39,
|
||||
"needYield" : 0,
|
||||
"saveState" : 0,
|
||||
"restoreState" : 0,
|
||||
"isEOF" : 1,
|
||||
"invalidates" : 0,
|
||||
"nWouldDelete" : 15,
|
||||
"nInvalidateSkips" : 0,
|
||||
"inputStage" : {
|
||||
"stage" : "FETCH",
|
||||
"filter" : {
|
||||
"b" : {
|
||||
"$gte" : 2
|
||||
}
|
||||
},
|
||||
"nReturned" : 15,
|
||||
"executionTimeMillisEstimate" : 0,
|
||||
"works" : 40,
|
||||
"advanced" : 15,
|
||||
"needTime" : 24,
|
||||
"needYield" : 0,
|
||||
"saveState" : 15,
|
||||
"restoreState" : 15,
|
||||
"isEOF" : 1,
|
||||
"invalidates" : 0,
|
||||
"docsExamined" : 39,
|
||||
"alreadyHasObj" : 0,
|
||||
"inputStage" : {
|
||||
"stage" : "IXSCAN",
|
||||
"nReturned" : 39,
|
||||
"executionTimeMillisEstimate" : 0,
|
||||
"works" : 40,
|
||||
"advanced" : 39,
|
||||
"needTime" : 0,
|
||||
"needYield" : 0,
|
||||
"saveState" : 15,
|
||||
"restoreState" : 15,
|
||||
"isEOF" : 1,
|
||||
"invalidates" : 0,
|
||||
"keyPattern" : {
|
||||
"a" : 1
|
||||
},
|
||||
"indexName" : "a_1",
|
||||
"isMultiKey" : false,
|
||||
"multiKeyPaths" : {
|
||||
"a" : [ ]
|
||||
},
|
||||
"isUnique" : false,
|
||||
"isSparse" : false,
|
||||
"isPartial" : false,
|
||||
"indexVersion" : 2,
|
||||
"direction" : "forward",
|
||||
"indexBounds" : {
|
||||
"a" : [
|
||||
"[2.0, inf.0]"
|
||||
]
|
||||
},
|
||||
"keysExamined" : 39,
|
||||
"seeks" : 1,
|
||||
"dupsTested" : 0,
|
||||
"dupsDropped" : 0,
|
||||
"seenInvalidated" : 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"ts" : ISODate("2017-08-30T10:55:19.142Z"),
|
||||
"client" : "127.0.0.1",
|
||||
"appName" : "MongoDB Shell",
|
||||
"allUsers" : [ ],
|
||||
"user" : ""
|
||||
}
|
9
src/go/tests/doc/script/profile/delete_all.js
Normal file
9
src/go/tests/doc/script/profile/delete_all.js
Normal file
@@ -0,0 +1,9 @@
|
||||
var coll = db.coll
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
coll.insert({a: i, b: i});
|
||||
}
|
||||
|
||||
coll.createIndex({a: 1});
|
||||
|
||||
coll.remove({a: {$gte: 2}, b: {$gte: 2}})
|
@@ -3,7 +3,7 @@
|
||||
"ID": "16196765fb4c14edb91efdbe4f5c5973",
|
||||
"Namespace": "samples.col1",
|
||||
"Operation": "query",
|
||||
"Query": "{\n \"find\": \"col1\",\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
"Query": "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
"Fingerprint": "FIND col1 find",
|
||||
"FirstSeen": "2017-04-10T13:16:23.29-03:00",
|
||||
"LastSeen": "2017-04-10T13:16:23.29-03:00",
|
||||
@@ -56,7 +56,7 @@
|
||||
"ID": "4e4774ad26f934a193757002a991ebb8",
|
||||
"Namespace": "samples.col1",
|
||||
"Operation": "query",
|
||||
"Query": "{\n \"find\": \"col1\",\n \"filter\": {\n \"s2\": {\n \"$gte\": \"41991\",\n \"$lt\": \"33754\"\n }\n },\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ]\n}",
|
||||
"Query": "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"filter\":{\"s2\":{\"$gte\":\"41991\",\"$lt\":\"33754\"}},\"shardVersion\":[0,\"000000000000000000000000\"]}}\n",
|
||||
"Fingerprint": "FIND col1 s2",
|
||||
"FirstSeen": "2017-04-10T13:15:53.532-03:00",
|
||||
"LastSeen": "2017-04-10T13:15:53.532-03:00",
|
||||
@@ -109,7 +109,7 @@
|
||||
"ID": "8cb8666ace7e54767b4d3c4f61860cf9",
|
||||
"Namespace": "samples.col1",
|
||||
"Operation": "query",
|
||||
"Query": "{\n \"find\": \"col1\",\n \"filter\": {\n \"user_id\": {\n \"$gte\": 3384024924,\n \"$lt\": 195092007\n }\n },\n \"projection\": {\n \"$sortKey\": {\n \"$meta\": \"sortKey\"\n }\n },\n \"shardVersion\": [\n 0,\n \"000000000000000000000000\"\n ],\n \"sort\": {\n \"user_id\": 1\n }\n}",
|
||||
"Query": "{\"ns\":\"samples.col1\",\"op\":\"query\",\"query\":{\"find\":\"col1\",\"filter\":{\"user_id\":{\"$gte\":3.384024924e+09,\"$lt\":1.95092007e+08}},\"projection\":{\"$sortKey\":{\"$meta\":\"sortKey\"}},\"shardVersion\":[0,\"000000000000000000000000\"],\"sort\":{\"user_id\":1}}}\n",
|
||||
"Fingerprint": "FIND col1 user_id",
|
||||
"FirstSeen": "2017-04-10T13:15:53.524-03:00",
|
||||
"LastSeen": "2017-04-10T13:15:53.524-03:00",
|
||||
|
Reference in New Issue
Block a user