Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-6768

MongoDB Profiler creates illegal documents

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major - P3
    • Resolution: Gone away
    • 2.0.4, 2.6.4, 2.7.6
    • None
    • Diagnostics
    • Linux (Debian). N/A, really.
    • Query

    Description

      The DB profiler creates illegal documents. These documents contain:
      1) keys with $ in the name
      2) keys with . in the name

      This problem makes working with these documents incredibly difficult.

      Here's an example:

      PRIMARY> test.record = db.system.profile.findOne({"ts" : ISODate("2012-08-12T14:26:18.806Z")})
      {
      	"ts" : ISODate("2012-08-12T14:26:18.806Z"),
      	"op" : "query",
      	"ns" : "gimmebar.collectionassets",
      	"query" : {
      		"$query" : {
      			"collection_id" : "redacted"
      		},
      		"$orderby" : {
      			"date" : -1
      		}
      	},
      	"ntoreturn" : 5,
      	"nscanned" : 169,
      	"scanAndOrder" : true,
      	"nreturned" : 5,
      	"responseLength" : 325,
      	"millis" : 227,
      	"client" : "redacted",
      	"user" : ""
      }
       
      PRIMARY> db.tmp_profiler_test.insert(testrecord)
      Tue Aug 14 18:39:40 uncaught exception: field names cannot start with $ [$query]

      The same thing happens for $orderby, $or, $set, etc., as well as for keys with "." in the name.

      I think the profiler should not create documents that can't be inserted. (I had to insert them into another collection because I wanted to filter the profiler data set, but I can't delete from a capped collection, which db.system.profile is.)

      I realize this changes the data format of the profiler, but it seems like the right move to me.

      As a workaround, for those developers who might stumble upon this, I managed to get the following transposition to work, but it's far from ideal:

      // recursion is fun
      function rename$(r) {
          for (k in r) {
              var changed = false;
              var newk = k;
              if (newk.indexOf(".") != -1) {
                  changed = true;
                  newk = newk.replace(".", "_DOT_", "g");
              }
              if (newk.indexOf("$") != -1) {
                  changed = true;
                  newk = newk.replace("$", "_DOLLAR_", "g");
              }
              if (changed) {
                  r[newk] = r[k];
                  delete r[k];
              }
              if (typeof r[newk] == "object") {
                  r[newk] = rename$(r[newk]);
              }
          }
          return r;
      }

      db.tmp_profiler_test.drop();
      db.system.profile.find(query_parameters).forEach(function(r) { r = rename$(r); db.tmp_profiler_test.insert(r);})

      (I also couldn't get this box to respect wiki markup, so editor: feel free to fix.) [Done.]

      Attachments

        Issue Links

          Activity

            People

              backlog-server-query Backlog - Query Team (Inactive)
              scoates Sean Coates
              Votes:
              1 Vote for this issue
              Watchers:
              13 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: