two strings query gte fields mongodb compare

strings - Condición de consulta MongoDb al comparar 2 campos



mongodb gte date (4)

En caso de que el rendimiento sea más importante que la legibilidad y siempre que su condición consista en operaciones aritméticas simples, puede usar la canalización de agregación. Primero, use $ project para calcular el lado izquierdo de la condición (tome todos los campos al lado izquierdo). Luego use $ match para comparar con una constante y filtro. De esta forma evitará la ejecución de javascript. A continuación está mi prueba en python:

import pymongo from random import randrange docs = [{''Grade1'': randrange(10), ''Grade2'': randrange(10)} for __ in range(100000)] coll = pymongo.MongoClient().test_db.grades coll.insert_many(docs)

Usando agregado:

%timeit -n1 -r1 list(coll.aggregate([ { ''$project'': { ''diff'': {''$subtract'': [''$Grade1'', ''$Grade2'']}, ''Grade1'': 1, ''Grade2'': 1 } }, { ''$match'': {''diff'': {''$gt'': 0}} } ]))

1 loop, lo mejor de 1: 192 ms por ciclo

Usando find y $ donde:

%timeit -n1 -r1 list(coll.find({''$where'': ''this.Grade1 > this.Grade2''}))

1 loop, lo mejor de 1: 4.54 s por loop

Tengo una colección T , con 2 campos: Grade1 y Grade2 , y quiero seleccionar aquellos con condición Grade1 > Grade2 , ¿cómo puedo obtener una consulta como en MySQL?

Select * from T Where Grade1 > Grade2


Puede usar $expr (operador de versión de 3.6 mongo) para usar las funciones de agregación en la consulta normal.

Comparar query operators versus aggregation comparison operators .

Consulta regular:

db.T.find({$expr:{$gt:["$Grade1", "$Grade2"]}})

Consulta de Agregación:

db.T.aggregate({$match:{$expr:{$gt:["$Grade1", "$Grade2"]}}})


Puede usar un $ donde. Solo tenga en cuenta que será bastante lento (tiene que ejecutar el código Javascript en cada registro) así que combine con las consultas indexadas si puede.

db.T.find( { $where: function() { return this.Grade1 > this.Grade2 } } );

o más compacto:

db.T.find( { $where : "this.Grade1 > this.Grade2" } );

UPD para mongodb v.3.6 +

puede usar $expr como se describe en la respuesta reciente


Si su consulta solo consiste $where operador $where , puede pasar solo la expresión de JavaScript:

db.T.find("this.Grade1 > this.Grade2");

Para un mayor rendimiento, ejecute una operación agregada que tenga una canalización $redact para filtrar los documentos que satisfagan la condición dada.

La tubería de $redact incorpora la funcionalidad de $project y $match para implementar la redacción a nivel de campo donde devolverá todos los documentos que coincidan con la condición usando $$KEEP y eliminará de la tubería los resultados que no coincidan con la variable $$PRUNE .

Al ejecutar la siguiente operación agregada, se filtran los documentos de manera más eficiente que usando $where para colecciones grandes, ya que esto utiliza una única canalización y operadores MongoDB nativos, en lugar de evaluaciones de JavaScript con $where , lo que puede ralentizar la consulta:

db.T.aggregate([ { "$redact": { "$cond": [ { "$gt": [ "$Grade1", "$Grade2" ] }, "$$KEEP", "$$PRUNE" ] } } ])

que es una versión más simplificada de la incorporación de las dos tuberías $project y $match :

db.T.aggregate([ { "$project": { "isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] }, "Grade1": 1, "Grade2": 1, "OtherFields": 1, ... } }, { "$match": { "isGrade1Greater": 1 } } ])

Con MongoDB 3.4 y más nuevo:

db.T.aggregate([ { "$addFields": { "isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] } } }, { "$match": { "isGrade1Greater": 1 } } ])