En mi aplicación, tengo una colección de 50 millones de datos. Estoy usando la búsqueda similar y luego cuento los resultados en un campo en particular (es decir, Nombre del paciente). También creé un índice en el campo Nombre del paciente, mejoró el rendimiento, pero aún lleva mucho tiempo.
db.patients.find({"Patientfirstname":{"$regex":"Testuser"}}).count() sin índice 40 segundos
db.patients.find({"Patientfirstname":{"$regex":"Testuser"}}).count() después de agregar el índice en el campo Patientfirstname 31 segundos
db.patients.find({"Patientfirstname":{"$regex":"Testuser"}}).count()Probé con un enfoque diferente (agregado) pero aún así, la respuesta es muy lenta
db.patients.aggregate.([{$match:{"Patientfirstname":{"$regex":"Testuser"}}}, {$project:{"Patientfirstname":1,"_id":1}}, {$group : {_id:"$Patientfirstname", count:{$sum:1}}}, {$sort:{"count":-1}} ])esta consulta también tarda lo mismo en obtener los resultados 31 segundos
se intentó otro enfoque pero los resultados no son correctos
seleccione solo el campo de toda la colección y luego aplique como buscar y contar y resultado.
db.patients.find({},{Patientfirstname:1,_id:1}).count({"Patientfirstname":{"$regex":"Testuser"}})la aplicación de un filtro en el conteo no funciona, se muestra el conteo completo de la colección. Ayude en esta consulta para obtener resultados más rápido. Gracias de antemano
Así que aquí está el trato:
Como se señaló correctamente en los comentarios, $regex es un operador que no funcionaría bien con o sin índices. Aquí está la razón por la cual:
Las consultas sin índices son lentas porque se ejecutaron con COLLSCAN, que es esencialmente una iteración de los 50 millones de documentos completos en el disco uno por uno, filtrando datos y devolviendo solo los que coinciden. El hecho de que los discos sean una pieza de hardware inherentemente lenta tampoco ayuda en la situación.
Ahora, cuando está indexado, MongoDB crea un B-Tree en la RAM. Y el operador $regex, que no es muy selectivo por naturaleza, fuerza un escaneo de árbol completo (en comparación con un escaneo de árbol reducido/parcial en caso de igualdades o rangos) en el índice b-tree, que es tan malo como un escaneo de colección en sí. . La única razón por la que obtiene un beneficio en 9 segundos es porque este Tree Scan ocurre en la RAM y no en el disco.
Dicho esto, hay algunas alternativas:
Para consultas de expresiones regulares que distinguen entre mayúsculas y minúsculas, si existe un índice para el campo, entonces MongoDB compara la expresión regular con los valores del índice, lo que puede ser más rápido que un escaneo de colección. Puede ocurrir una mayor optimización si la expresión regular es una "expresión de prefijo", lo que significa que todas las posibles coincidencias comienzan con la misma cadena. Esto permite que MongoDB construya un "rango" a partir de ese prefijo y solo coincida con los valores del índice que se encuentran dentro de ese rango.
Una expresión regular es una "expresión de prefijo" si comienza con un signo de intercalación (^) o un ancla izquierda (\A), seguida de una cadena de símbolos simples. Por ejemplo, la expresión regular /^abc.*/ se optimizará haciendo coincidir solo los valores del índice que comienzan con abc.
Además, mientras que /^a/, /^a. /, y /^a. $/ coincide con cadenas equivalentes, tienen diferentes características de rendimiento. Todas estas expresiones usan un índice si existe un índice apropiado; sin embargo, /^a. /, y /^a. $/ son más lentos. /^a/ puede dejar de escanear después de hacer coincidir el prefijo.
Las consultas de expresiones regulares que no distinguen entre mayúsculas y minúsculas generalmente no pueden usar índices de manera efectiva. La implementación de $regex no reconoce la intercalación y no puede utilizar índices que no distingan entre mayúsculas y minúsculas.
Cree un índice de texto : esto tokenizaría su cadena de texto y permitiría búsquedas más rápidas basadas en texto
Si está implementado en MongoDB Atlas, puede usar Atlas Search , que es un motor de búsqueda de texto basado en Lucene (funciona casi como elasticsearch con esteroides). Esto ofrece un rendimiento y funcionalidades significativamente mayores, como búsqueda de texto difuso, autocompletado de texto, etc.