blog

Buscar por una propiedad en un archivo json con nodejs

El algoritmo lo realicé en Javascript (ES6), lo utilicé para un proyecto en la empresa en la que actualmente estoy trabajando, más específicamente en la funcionalidad de búsqueda de archivos. Al principio pensé en crear un método POST en backend para buscar por cada uno de los directorios del FTP, pero al listar cada directorio se crea una nueva conexión, ésto para un usuario que esté navegando por el sitio no genera tanto impacto, pero para el servidor la tarea se vuelva más compleja y si va a repercutir bastante por lo que deseché la idea.

Luego pensé en generar un mapeo global de todos los directorios y archivos del FTP por lo que creé un algoritmo para dicha tarea, después de ésto me topé con un problema y era la lectura del archivo JSON, para el cuál creé el siguiente algoritmo (se encuentran comentados las líneas de código).

Fragmento del Archivo JSON Mapeado


[{
  "name": "Nombre",
  "type": "directory",
  "subDirectory": [{
    "name": "NOMBRE DEL DIRECTORIO",
    "type": "directory",
    "subDirectory": [{
      "name": "ARCHIVO.docx",
      "type": "file",
      "subDirectory": []
    }]
  }]
}]


Algoritmo de Búsqueda

La variable fs y el método readFileSync vienen de un paquete de NodeJS para la administración de archivos del sistema (lectura, escritura), pueden ver más información en el siguiente enlace.



let readFile = searchParam => {
    // Leer el archivo json
    let json = JSON.parse(fs.readFileSync(`archivo.json`, 'utf8'));

    // Si no existe el archivo retornar un error
    if (!json)
        return 'Se ha encontrado un error, el archivo json no existe';

    // En esta variable se guardará la lista de resultados
    let filtered = searchStringInJson(json, searchParam.trim().toLowerCase());
};

let searchStringInJson = (source, name) => {
    // Lista donde se van a guardar los resultados
    let itemList = [];

    for (key in source) {
        let item = source[key];

        // Esto puede ser modificado a tu gusto, pero para el algoritmo que estaba desarrollando no necesito los directorios, solamente los archivos
        if (item.name.trim().toLowerCase().includes(name) && item.type !== 'directory')
            itemList.push(item);

        // Si el elemento contiene un subdirectorio entrar a la lista y recursivamente buscar
        if (item.subDirectory && item.subDirectory.length > 0) {
            // Buscar recursivamente los elementos y obviar todos los resultados que sean de tipo directory
            let subresult = searchStringInJson(item.subDirectory, name.trim().toLowerCase()).filter(i => i.type !== 'directory');

            // Si encuentra resultados agregarlos a la lista
            if (subresult !== undefined && subresult.length > 0) {
                subresult.map(item => { itemList.push(item); });
            }
        }
    }

    // Retorna toda la lista de resultados
    return itemList;
}