Tenga en cuenta el comando unas líneas más abajo en la documentación que vinculó:
Esto le indica que los campos inexistentes y los campos establecidos en nulo se tratan de manera especial.
Para los documentos {}
y {a: null}
para ser equivalente en el orden de clasificación, el algoritmo de clasificación debe considerar que el campo de clasificación faltante está presente y tener un valor de null
.
Si agrega explícitamente el campo que falta, solo para ver cómo se ve, el orden tiene más sentido.
El filtro {tag: { $gte: { baz: MinKey() }}}
aplicado a {_id: 1, tag: {bar: "BAR"}}
esencialmente está comparando {baz: MinKey()}
con {baz: null, bar: "BAR"}
.
Cerca de la parte superior de la documentación que vinculó, dice que MinKey
es menor que null
, por lo que ese es el orden correcto.
EDITAR
En general, la consulta es más eficaz cuando los nombres de campo no son datos en sí mismos. En términos de una base de datos tabular, ¿qué columna contendría "baz"?
Un ligero cambio en el esquema simplificaría este tipo de consulta. En lugar de {tagname: tagvalue}
, use {k:tagname, v:tagvalue}
. A continuación, podría indexar tag.k
y/o tag.v
y consulta en tag.k
para buscar todos los documentos con una etiqueta "baz", la consulta de etiquetas con operaciones de desigualdad funcionaría de forma más intuitiva.
db.collection.find({"tag.k":{$gte:"baz"}})
Las coincidencias exactas se pueden hacer con elemMatch como
db.collection.find({tag: {$elemMatch:{k:"baz",v:"BAZ"}}})
Si realmente necesita que los documentos devueltos contengan {tagname: tagvalue}
, el $arrayToObject
el operador de agregación puede hacer eso:
db.collection.aggregate([
{$match: {
"tag.k": {$gte: "baz"}
}},
{
$addFields: {
tag: {$arrayToObject: [["$tag"]]}
}}
])