Anexo: Sintaxis de búsqueda reducida y de mongoDB

Se pueden usar comandos de búsqueda en BD de 3 formas distintas:

- en conceptos de clase Búsqueda

- en la Búsqueda general de BD o en el campo de Búsqueda (en lenguaje natural) de la esquina sup. derecha de la página, si la base está indizada y el usuario pertenece al grupo administradores o expertos (admin / g1). 

- en las funciones de Procedimientos javascript que admiten una búsqueda reducida de Medea o directamente un find() de mongoDB.

Normalmente esta sintaxis de búsqueda incluso, la simplificada de Medea, sólo es usada por administradores, no por el usuario de perfil habitual.

 

IMPORTANTE: Si en el campo que admite un comando de búsqueda se encuentra un objeto entre llaves { }, se considera una búsqueda find() directamente contra el motor de BD mongoDB, con su sintaxis y el formato: {find:{}, data:{}, sort:{}, limit...}. Puede ver la referencia en: Mongo find()

También se admite un formato find como {cla:'tarpre', ope:'ope.IOA' }

En BD es muy raro que haya un campo con un valor null grabado, porque el interface elimina estos campos al asignarles ese valor, pero a través de script o al producirse un error de referencias u otros casos, puede existir. Para buscarlos no basta el lenguaje abreviado, hay que buscarlos con un find como {cla:'tarpre', ope:null}. Para los administradores, en el campo JSON de un documento mongodb se visualizarían estos campos null.

Esta sintaxis también permite buscar objetos o listas vacías como: {plis:{}} o {desl:[]} (es decir, cualquier concepto con pliegos pero nulos, o una lista de descompuestos vacía).

Se pueden unir varias condiciones (operador AND) separándolas con espacio en blanco, o hacer una condición OR con una barra vertical ( | ), sólo entre dos campos, no se pueden encadenar condiciones OR, ni anidarlas.

El uso de la sintaxis más habitual en expresiones regulares de búsqueda PCRE (las de Perl también usadas en mongoDB) en el Anexo de Expresiones regulares

La correspondencia de la sintaxis simplificada de uso común, con el lenguaje de BD:

 

ATENCIÓN, CASOS IMPORTANTES:

1. La comparación del contenido entre dos campos se tiene que hacer con la cláusula where, como: cla=act where=this.fecini==this.fecfin  o  cla=act where=obj.fecini>obj.fecfin

2. las búsquedas de tipo NOT IN (y sobre todo mediante expresiones regulares), seleccionando una lista de documentos y devolviendo su complementario, son muy costosas en el motor de BD y se deben reducir al máximo, filtrando antes por clase y otros valores de campo.

3. El campo a la izquierda de la expresión, puede ser "el campo _id al que hace referencia otro campo", por ejemplo: si una clase de documentos unidad documental (udo) tiene una lista de referencias a sus autores (autarql), se puede buscar:
· cla=udo autarql._id=autarq.N150 : las unidades documentales que tengan en su lista de autores el de _id autarq.N150
· cla=udo autarql._id=(autarq.N150,autarq.N120,autarq.N122) : lo mismo buscando en un grupo de 3 autores

 

Sintaxis reducida Medea Búsqueda mongoDB find(): Significado
identificador {find:{'_id':'identificador'}} un único concepto
cla==cod_superclase {find:{"cla":{"$in":["cod_superclase", "cod_subclase1", "cod_subclase2" ,...]}} concepto de una clase o cualquiera de sus subclases a cualquier nivel
campo! {find:{'campo':{"$exists":false}}} no existe el campo (no está puesto campo=null, sino que no se graba en BD)
campo!! {find:{'campo':{"$exists":true}}} existe el campo
limit=num {find:{limit: num}} devuelve sólo los primeros 'num' valores según el criterio de ordenación aplicado
campoLista.size=entero {find:{"campoLista":{"$size":entero}}}  Compara buscando por la longitud de un array o lista
campoLista.indice!! find:{"campoLista.indice":{"$exists":true}} Comprueba si existe en la lista el elemento indice. Por ejemplo gral.2!! -> ¿existen al menos 3 imágenes?
campo=valor {find:{"campo": valor}} concepto con valor (numérico o alfanumérico) en un campo. Por defecto, si sólo hay una condición se considera el campo _id y se puede omitir campo=
campo>=valor {find:{"campo":{"$gte":valor}}}  expresión de comparación. Otras correspondencias similares: 
> ($gt)   >= ($gte)   > ($lt)   <= ($lte)   != ($ne)
'<usu>'   Macro que sustituye esos 5 caracteres por el código de usuario actualmente validado en BD. Útil para seleccionar y comparar con personas, grupos de trabajo etc. relacionados con el usu.
campo1=valor campo2<valor {find:{"campo1": valor, "campo2":{"$lt": valor}}} condición AND: el espacio en blanco entre dos campos indica que se cumpla la primera y la segunda
campo1=valor | campo2<valor {find:"$or":[{"campo1": valor},{"campo2":{"$lt": valor}}]} condición OR: una barra vertical significa que se cumpla una O la otra
campo=/expr_regular/ {find:{campo:{"$regex":'expr_regular'}}} valor de un campo coincidente con una expresión regular, como una máscara:   ^(inicio) $(final) .(cualquiera) *(0 ó más caracteres) +(1 ó más caracteres) ?(0o1) [...](alguno) [^...](ninguno).
Se admiten todos los modificadores de expresión regular como por ejemplo /expr_regular/i que ignora mayúsculas/minúsculas, equivale a find:{campo:{"$regex":valor,"$options":"i"}}}
Se ha implementado internamente también la expresión != (distinto) a la expresión regular
campo=[listaValores] {find:{"campo":{"$in":[valor1,valor2... ]}}} búsqueda dentro de una lista de valores concretos. Si la expresión es != (distinto) sería excluido de la lista de valores ($nin)
campo1=(tabla.campo2) {find:{"campo":{"$in":[valor1,valor2, ... ]}},sort:{"_id":1}} con = cruce de referencias, devuelve los documentos a los que se hace referencia en el campo indicado entre paréntesis.
Si la expresión es un signo != (distinto), la búsqueda sería NOT IN la lista de valores del campo (en color azul). NO SE PUEDEN especificar varias en la misma búsqueda.
where="expr_con_operadores" {find:{condición,"$where":"expr_con_operadores"}} Expresión de filtro, como una subconsulta pero sin cruzar identificadores, es decir, siempre operando con campos de la misma clase. La expr_con_operadores es con sintaxis javascript. Ejemplo:
cla=gra where="obj.tam >= obj.oritam && obj.anc!"
consulta<lista _id> => campo<lista _id> mongo.distinct(campo,busqueda) Subconsulta similar a un JOIN de SQL usando el operador => entre la consulta y uno de los campos de los conceptos devueltos. Proyecta una selección de _ids sobre otra devolviendo una 3ª lista de _ids coincidentes, con una sola aparición
campo#tipo {find:{"campo":{"$type": "tipo"}}}   buscar por tipo de campo javascript: 1-Double 2-String 3-Objeto 4-Array 5-BinayData 7-objectId 8-Boolean 9-Date 10-null 11-regularExpression 13-avaScript 16-Integer 17-timeStamp 18-long entero de 64 bits 19-decimal de 128... y otros obsoletos
campoLista.ind!!
y
campoLista.size=num

{find:{"campoLista.3":{"$exists": true}}}  
y
{find:{"campoLista":{"$size": 2}}}  
 
se puede preguntar por la existencia de una posición de un array (como gral.3!!, lo que significa que al menos existen 4 imágenes), o bien por un tamaño concreto (como gral.size=4)
campo[+-] {sort: {"campo":1}} ordenación ascendente (+). Descendente con signo -, que se traduce en mongoDB con el valor -1)

 

Ejemplos:

- Todas las clases: /^\./ o {_id:/^\./}

- Tareas con incidencias ordenadas por clase y fecha de cierre : cla==tar numinc!! cla+ feccer-

- Tareas programadas fuera del mes jul-2016 : cla==tar fecpro>20160700 fecpro<20160800

- Correctivas pendientes de programación : cla=tarcor fecpro!

- Tareas preventivas abiertas, ordenadas por Fecha programada, espacio y de forma descendente por clase · código : cla=tarpre feccer! fecpro+ esp+ _id-

- Conceptos de clase distrito o bin, orden comenzando por distritos: cla=["espdis","bin"] cla-

- Supongamos una clase de conceptos bin que tiene una lista de componentes cmpl (de clase cmp)
   La búsqueda de 'Componentes que tengan bin' : (bin.cmpl._id)
   La búsqueda 'Componentes SIN bin': cla=cmp _id=(bin.cmpl._id!)

- Carpetas con más de 2 imágenes (hay que filtrar primero los que tienen gral, sino dará error al comparar) : cla=car gral!! where="this.gral.length>2"

- Carpetas sin descendientes (ojo a la igualdad con dos ==): cla=car desl!! where="this.desl.length==0"   (Medea se ocupa de no guardar estos objetos, pero un script podría guardar valores incorrectos como esos)

 

Otro ejemplo más completo:

búsqueda:    'Tareas (de cualquier subclase), que tengan fecha programada y con fecha de cierre posterior al 1/1/2016'

sintaxis reducida de Medea:    cla==tar fecpro!! feccer>20160001

sintaxis find() de mongoDB:   {find:{"cla":{"$in":["tar","tarcor","tarpre"]},"fecpro":{"$exists":true},"feccer":{"$gt":20160001}}, sort:{"_id":1}}

 

Búsquedas más avanzadas (principalmente para administradores):

- Buscar una única repetición de proyectos, seleccionando de una tabla de personas (per), y los proyectos de su tabla de relaciones (lista de precios, prel): cla==per => prel.pry

Otro ejemplo, para el caso de programar operaciones: Buscar las zonas que son apuntadas por elementos de inventario de distintas clases, filtrados por alguna condición: (cla==SUP tipo=SI => ZG),
Las subclases de SUP (distintas superficies) tienen un campo 'tipo', queremos seleccionar las superficies de tipo SI y seleccionar sólo los _id de la clase zona (ZON) apuntadas por el campo SUP.ZG. El paréntesis devuelve los _id pero en general no es obligatorio _id=( ... )

- Para eliminar una gran lista de clases, como estos conceptos son especiales y no se pueden eliminar seleccionando masivamente, en la pestaña Menú > Base de datos > Búsquedas se pueden seleccionar con: cla='' cod!=['','O','A','car','usu','pro'] Indicando en la lista las clases que queremos mantener y pulsando Elimina documentos...

- Imágenes con tamaño mayor o igual que original, aplicando con sintaxis mongoDB un filtro WHERE:
{find:{cla:"gra","$where":"obj.tam >= obj.oritam && obj.anc!"}}

- La misma con sintaxis abreviada Medea: cla=gra tam!! where="obj.tam >= obj.oritam && obj.anc!"

- Imágenes con las extensiones habituales (mediante una expresión regular): cla==gra cod=/\.png$|\.jpg$|\.jpeg$/i

- Imágenes con códigos con espacio en blanco: /.\s[.]jpg/i

Procedimientos javascript

El procedimiento más sencillo para devolver una lista de conceptos con una búsqueda concreta sería como:

  bas.leeConceptos("cla=car res=Preventivas", cb);

Devuelve la lista de conceptos de clase carpeta con resumen exactamente igual a "Preventivas"

Si creamos dos parámetros con los códigos clase y resumen, para admitir un código de clase y una expresión con la que comparar el campo resumen de las carpetas, podríamos ponerla:

   bas.leeConceptos("cla="+vals.clase+" res=/"+vals.resumen+"/i num-", cb);

Ambas devuelven una lista con los conceptos que cumplen el criterio de la búsqueda,

Otras formas de recuperar información

Otros 2 métodos para buscar información en la BD de forma más general son:

- Lista de conceptos de una clase. Nos da todos los elementos, que se pueden filtrar con los campos del formulario de búsqueda que tiene cada clase en la persiana Búsqueda. Son todos los campos de la clase que no estén restringidos por el administrador en los formularios de búsqueda.

- Lista de conceptos de una clase filtrados por el valor de un campo de tipo lista (clasificación). Haciendo clic en el icono de la línea de definición del campo, se muestra la lista de todos los posibles valores y haciendo clic en uno de los valores, se muestra la lista de conceptos asociados a ese,