Notera kommandot några rader ner i dokumentationen du länkade:
Detta talar om för dig att icke-existerande fält och fält inställda på null behandlas speciellt.
För dokumenten {} och {a: null} för att vara ekvivalent i sorteringsordning måste sorteringsalgoritmen överväga att det saknade sorteringsfältet finns och ha värdet null .
Om du uttryckligen lägger till det saknade fältet, bara för att se hur det ser ut, är beställningen mer meningsfull.
Filtret {tag: { $gte: { baz: MinKey() }}} tillämpas på {_id: 1, tag: {bar: "BAR"}} jämför i huvudsak {baz: MinKey()} med {baz: null, bar: "BAR"} .
Nära toppen av dokumentationen du länkade står det att MinKey är mindre än null , så det är rätt ordning.
REDIGERA
I allmänhet är förfrågningar mest effektivt när fältnamnen inte själva är data. När det gäller en tabelldatabas, vilken kolumn skulle innehålla "baz"?
En liten förändring i schemat skulle förenkla denna typ av fråga. Istället för {tagname: tagvalue} , använd {k:tagname, v:tagvalue} . Du kan sedan indexera tag.k och/eller tag.v , och fråga på tag.k för att hitta alla dokument med en "baz"-tagg skulle fråga efter taggar med ojämlikhetsoperationer fungera mer intuitivt.
db.collection.find({"tag.k":{$gte:"baz"}})
Exakta matchningar kan göras med elemMatch like
db.collection.find({tag: {$elemMatch:{k:"baz",v:"BAZ"}}})
Om du verkligen behöver att de returnerade dokumenten ska innehålla {tagname: tagvalue} , $arrayToObject aggregeringsoperatör kan göra det:
db.collection.aggregate([
{$match: {
"tag.k": {$gte: "baz"}
}},
{
$addFields: {
tag: {$arrayToObject: [["$tag"]]}
}}
])