feliixx / mongoplayground

a simple sandbox to test and share MongoDB queries
https://mongoplayground.net
GNU Affero General Public License v3.0
180 stars 11 forks source link

MongoDB v6.0.2 or mongoplayground bug? #153

Open rickhg12hs opened 1 year ago

rickhg12hs commented 1 year ago

While exploring ways to retrieve or "$merge"/"$out" unique documents from a collection, I ran across the following "oddity".

mongoplayground.net example

mongoplayground mgodatagen configuration:

[
  {
    "collection": "collection",
    "count": 100,
    "content": {
      "key1": {
        "type": "int",
        "minInt": 0,
        "maxInt": 1
      },
      "key2": {
        "type": "int",
        "minInt": 0,
        "maxInt": 1
      }
    }
  }
]

Query:

db.collection.aggregate([
  {
    "$unset": "_id"
  },
  {
    "$group": {
      "_id": "$$ROOT"
    }
  },
  {
    "$replaceWith": "$_id"
  }
])

Result: (should just be 4 docs, but it's not - there are repeats)

[
  {
    "key1": 1,
    "key2": 1
  },
  {
    "key1": 1,
    "key2": 0
  },
  {
    "key1": 1,
    "key2": 0
  },
  {
    "key1": 1,
    "key2": 1
  },
  {
    "key1": 0,
    "key2": 0
  },
  {
    "key1": 0,
    "key2": 1
  },
  {
    "key1": 0,
    "key2": 0
  },
  {
    "key1": 0,
    "key2": 1
  }
]

Using the same collection and query on MongoDB Atlas, the expected output of just 4 documents was produced.

The MongoDB Atlas Cluster I used is at version 5.0.13 so maybe it's a MongoDB server regression?

rickhg12hs commented 1 year ago

I have another data point, I think.

TLDR; I think object field ordering isn't preserved when creating the MongoDB collection.

Rather than splash some more configs and queries here, I just supply the mongoplayground.net links.

Here's a mongoplayground.net where the results are not consistent. Hitting run several times, sometimes the output is correct (essentially converting an array to a set) and sometimes the result has repeat elements in the array.

Here, the mongoplayground.net has the same query, except the objects in the array are rewritten. The result is consistent and correct.

Does this mean that documents written to the collection have randomly/inconsistently ordered objects?

This would also explain the "oddity" described in my first comment above.

feliixx commented 1 year ago

TLDR; I think object field ordering isn't preserved when creating the MongoDB collection.

Exactly. It's exactly what's happening here, for example in mongosh

use test
db.test.insertOne({a:1,b:0})
db.test.insertOne({b:0,a:1})
db.test.aggregate([ { "$unset": "_id" }, { "$group": { "_id": "$$ROOT" } }, { "$replaceWith": "$_id" }])

Result: [ { a: 1, b: 0 }, { b: 0, a: 1 } ]

Sadly, it's the driver that's responsible of this. It's actually the same root cause as #150... So another good reason to try to fix this field reordering issue!

johachi commented 9 months ago

Could this also be related to https://github.com/feliixx/mongoplayground/issues/171 regarding getting inconsistent results?