Filtro de Mongo funciona dentro de la terminal de Mongo, pero no funciona cuando se escribe en Go.
Mongo: 4.4
Go: 1.17.3
Estoy intentando obtener documentos con valores de campo de cadena más largos que cuatro símbolos.
Aquí está la consulta que uso dentro de la consola de mongo:
db.player.find({
"name": { "$exists": true },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 4 ] }
})
Y aquí está la misma consulta pero codificada como filtro “bson” en “go”:
longName := bson.M{
"name": bson.M{"$exists": true},
"$expr": bson.M{
"$gt": bson.A{
bson.M{"$strLenCP": "$name"},
4,
},
},
}
fmc, err := collection.Find(context.TODO(), longName)
if err != nil {
log.Panic(err)
}
var longBoi models.Player
err = fmc.Decode(&longBoi)
if err != nil {
log.Panic(err)
// pánico aquí:
// 2021/12/15 15:53:46 EOF
// panic: EOF
}
La primera consulta devolverá los documentos deseados con valores de campo de cadena de longitud mayor a un número específico. La segunda consulta dará un error con el mensaje “EOF”, un sello de tiempo y una pila de llamadas. El depurador indica que el lote “batch” dentro del cursor “fmc” no contiene datos.
¿Qué está mal en el segundo caso?
davy.ai
El problema en el segundo caso es que el método
Decode
solo puede decodificar un único documento de la colección de resultados. Cuando se utiliza el métodoFind
en el controlador de MongoDB para Go, la colección de resultados se retorna como un cursor que debe ser iterado para recuperar todos los documentos que coinciden con la consulta. En otras palabras, el métodoDecode
debe ser llamado múltiples veces hasta alcanzar el final de la colección de resultados.Para solucionar el problema, el código debe utilizar un ciclo para iterar sobre el cursor y decodificar todos los documentos. Aquí tienes un ejemplo:
Este código iterará sobre el cursor utilizando el método
Next
, decodificará cada documento utilizando el métodoDecode
y lo agregará a una slice demodels.Player
. Finalmente, el código verifica si ocurrieron errores durante la iteración utilizando el métodoErr
.Ten en cuenta que el método
Find
retorna un cursor que debe ser cerrado explícitamente después de la iteración utilizando el métodoClose
.