Descripción general
JavaScript es el lenguaje de scripting predeterminado de Fess a partir de la versión 15.9. Se ejecuta sobre Sai (un fork de Nashorn desarrollado por CodeLibs, que Fess ya utiliza para las expresiones de sus XML de DI), y los scripts se ejecutan como ECMAScript 6. Su identificador es javascript, y también puede indicarse mediante los alias js y sai.
Cómo se evalúan los scripts
El motor de scripting de Fess primero intenta compilar el texto del script como una única «expresión». Solo si eso falla al analizarse, vuelve a compilar el texto como un bloque de «sentencias».
Por esta razón, tanto una expresión simple que solo devuelve un valor:
como un script que contiene una sentencia return de nivel superior:
funcionan sin problemas. Lo segundo normalmente sería un error de sintaxis en JavaScript puro, ya que un return de nivel superior no está permitido. Pero como no se puede compilar como expresión, se reinterpreta como un bloque de sentencias y se ejecuta como un script válido.
En los lugares donde cada línea se trata como una única expresión, como en los scripts de data store, no se puede usar un script formado por varias sentencias. En los lugares donde se evalúa el script completo, como en los trabajos programados, puede usar libremente sentencias de varias líneas, declaraciones de variables let / const y estructuras de control.
Advertencia
Un script que se compila como bloque de sentencias solo devuelve un valor si contiene un return explícito. Cuando el texto no se puede analizar como expresión, se envuelve en una función y se ejecuta como un bloque de sentencias, y un bloque sin return se evalúa como null. Basta con un punto y coma final para cruzar esa línea:
| Script | Resultado | Motivo |
|---|---|---|
content.length() | 11 | Se analiza como expresión; el valor de la expresión es el resultado |
content.length(); | null | Solo se analiza como bloque de sentencias, que no contiene return |
var x = 1; x + 2 | null | Solo se analiza como bloque de sentencias, que no contiene return |
En Groovy los tres devolvían un valor, porque allí el valor de la última sentencia evaluada es el valor de retorno del script. JavaScript no tiene esa regla.
Esta es la única diferencia de la migración que no produce ningún error, ninguna línea de registro ni ningún síntoma más allá de un campo que se queda vacío en silencio: un mapeo de data store cuyo script devuelve null simplemente no establece ese campo. Escriba cada línea campo=expresion de un data store como una expresión pura sin punto y coma final, y dé a todo script de trabajo programado un return explícito.
Sintaxis básica
Una línea sin punto y coma final es a continuación una expresión y puede usarse en cualquier sitio, incluida una línea campo=expresion de un data store. Las declaraciones ( let / const ), los bloques if y los bucles son sentencias: solo pueden usarse allí donde se evalúa el script completo, como en un trabajo programado, y el script debe contener un return explícito para producir un valor. Consulte «Cómo se evalúan los scripts» más arriba.
Declaración de variables
Operaciones de cadenas
Operaciones de colecciones
Estructuras condicionales
Bucles
Scripts de Data Store
Ejemplos de scripts en configuración de data store.
Nota
En los scripts de data store, cada línea campo=expresion se evalúa de forma independiente como una única expresión. Por lo tanto, no se pueden usar declaraciones de variables como let / const ni estructuras de control multilínea que establezcan varios campos a la vez (como bloques if). Al usar clases Java, escríbalas como una única expresión con el nombre de clase completamente calificado (FQCN), y use el operador ternario por campo para los valores condicionales (por ejemplo, url=data.published ? data.url : null ). Además, el nombre de variable data usado aquí es solo un ejemplo; el nombre de variable real depende del conector de data store utilizado. Consulte Rastreo de Almacén de Datos para más detalles. Escriba la expresión sin punto y coma final: una línea que solo puede analizarse como bloque de sentencias se evalúa como null y el campo se queda sin establecer; consulte Cómo se evalúan los scripts.
Mapeo básico
Generación de URL
Procesamiento de contenido
Procesamiento de fechas
Objetos disponibles
Los objetos disponibles en los scripts varían según el contexto de ejecución.
| Contexto | Objeto | Descripción |
|---|---|---|
| Todos los contextos | container | Contenedor DI. Se usa para acceder a los componentes mediante container.getComponent("...") |
| Trabajos programados | executor | Control de ejecución de trabajos ( JobExecutor ). Necesario para el soporte de detención de trabajos |
| Data Store | (específico del conector) | Variables de registro de datos proporcionadas por cada data store. El nombre de la variable depende del conector |
| Mapeo de rutas | url , matcher | La cadena de URL a convertir y el resultado de coincidencia de expresión regular ( Matcher ). Disponible cuando el reemplazo lleva el prefijo del nombre de un motor registrado, por ejemplo javascript: (alias js:, sai:) |
| Boost de documento | (campos del documento) | Cada campo del documento objetivo está disponible como variable (se usa en expresiones de condición y de valor de boost) |
Scripts de trabajos programados
Ejemplos de scripts JavaScript para trabajos programados. En los trabajos programados, container y executor están disponibles. Pasar executor al método execute() del trabajo habilita el control de detención del trabajo.
Nota
Un script de trabajo programado se evalúa como un único script completo. El motor de scripting primero intenta compilarlo como expresión y solo lo reinterpreta como un bloque de sentencias si eso falla, por lo que se pueden usar sentencias de varias líneas, declaraciones let / const, estructuras de control y una sentencia return de nivel superior (consulte «Cómo se evalúan los scripts» más arriba). Los ejemplos de «Uso de clases Java», «Acceso a componentes de Fess», «Manejo de errores» y «Depuración y salida de logs» que aparecen a continuación también asumen este contexto de script completo.
Ejecución de trabajo de crawl
Crawl condicional
Ejecución secuencial de múltiples trabajos
Uso de clases Java
Dentro de los scripts JavaScript, gracias a la interoperabilidad con Java de Sai (Nashorn), puede usar directamente la biblioteca estándar de Java y las clases de Fess. JavaScript no tiene sentencia import, por lo que las clases siempre se escriben con su nombre completamente calificado (FQCN).
Fecha y hora
Operaciones de archivo
Comunicación HTTP
Advertencia
El acceso a recursos externos afecta el rendimiento, manténgalo al mínimo necesario.
Acceso a componentes de Fess
Puede acceder a los componentes de Fess usando container.
System Helper
Obtención de valores de configuración
Ejecución de búsqueda
Manejo de errores
JavaScript no tiene sentencia import, por lo que no aplican las restricciones de ubicación de Groovy. Puede capturar excepciones con try-catch para controlar los errores del trabajo.
Depuración y salida de logs
Salida de logs
Salida de depuración
Si desea inspeccionar rápidamente el contenido de una variable, conviértala en cadena con JSON.stringify y regístrela en el log.
Migración desde Groovy
Tenga en cuenta las siguientes diferencias al migrar un script Groovy existente a JavaScript.
Precisión aritmética
Las operaciones numéricas de JavaScript siempre usan coma flotante de doble precisión. Por ejemplo, la siguiente expresión devuelve el entero 34 en Groovy, pero el número de coma flotante 34.0 en JavaScript.
Por otro lado, el tipo de retorno de un método invocado a través de la interoperabilidad con Java conserva el tipo del lado Java, por lo que content.length() sigue devolviendo un entero.
Reescritura de sintaxis exclusiva de Groovy
La siguiente sintaxis exclusiva de Groovy debe reescribirse para JavaScript.
| Groovy | JavaScript | Descripción |
|---|---|---|
1000L | 1000 | El sufijo L de literal long no es necesario; escriba el número literal tal cual |
["a", "b"] as String[] | ["a", "b"] | Un array de JavaScript se convierte automáticamente en un array de Java al pasarlo a un método que espera |
Interoperabilidad con Java
La notación de la interoperabilidad con Java es la misma que la de Nashorn, y es casi idéntica a la de Groovy. Las llamadas a constructores totalmente calificados como new java.io.File(...), java.lang.System.getProperty(...) y new org.codelibs.fess.job.IndexExportJob() se resuelven tal cual.
Sintaxis ES6
Dado que el motor JavaScript de Fess se ejecuta como ECMAScript 6, puede usar sintaxis ES6 como let / const, funciones flecha, literales de plantilla, desestructuración, for...of y class. Sin embargo, el encadenamiento opcional (?.) y el operador de fusión nula (??) son sintaxis de ES2020 en adelante y no se pueden usar.
Mejores prácticas
Mantenerlo simple: Evitar lógica compleja, escribir código legible
Valores por defecto: Use el operador OR lógico (
||) en lugar del operador ElvisManejo de excepciones: Manejar errores inesperados con try-catch apropiado
Salida de logs: Registrar logs para facilitar la depuración
Rendimiento: Minimizar acceso a recursos externos
Operaciones numéricas: Donde se espera un entero, use directamente el resultado de una llamada a un método por interoperabilidad con Java, o conviértalo explícitamente si es necesario
Información de referencia
Descripción general del scripting - Descripción general de scripting
Guía de scripting Groovy - Guía de scripting Groovy (plugin)
Rastreo de Almacén de Datos - Guía de configuración de data store
Programador de Tareas - Guía de configuración del programador