Una búsqueda que cuenta secretos
Los permisos de una búsqueda significan que cada persona solo encuentra lo que puede leer. La frescura significa que el texto borrado o antiguo desaparece del índice. Ambos importan porque la búsqueda copia tus documentos a otro sitio, y la copia ignora las reglas del original.
Una estudiante busca «fechas de vacaciones» y recibe una página de nóminas. O una norma borrada sigue respondiendo.
Al final de esta lección
Nota
Puedo mantener una búsqueda dentro de lo que cada persona puede ver y hacer que un borrado o una versión nueva lleguen al índice.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Filtro de acceso | una regla que conserva solo lo que una persona puede leer |
| Grupo | un conjunto con nombre de personas que comparten acceso |
| Caducado | una copia más antigua que la versión actual |
| Versión | un número que sube cada vez que cambia un documento |
| Marca de borrado | un registro de que algo se borró |
| Fuga | mostrar algo a quien no puede verlo |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Filtra antes de ordenar, nunca después
Cada trozo lleva los grupos que pueden leerlo, una clase de metadato. Al consultar, la búsqueda conserva solo los trozos que permiten los grupos de quien pregunta, y luego toma los k mejores.
Filtrar después de los k primeros falla dos veces. Una página oculta ocupa un puesto, así que la persona recibe menos resultados de los que debería. Y un recuento de «3 resultados, 2 ocultos» le dice que esas páginas existen.
Ejemplo resuelto: Ana busca fechas de vacaciones
| Método | Resultados para Ana | Qué falla |
|---|---|---|
| Filtrar después de los 2 primeros | e1 | Una página de nóminas ocupó un puesto y luego se ocultó |
| Filtrar antes de los 2 primeros | e1, e3 | Nada |
| Filtrar antes, caducadas fuera | e1 | La copia antigua e3 desaparece |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un borrado debe llegar al índice
El índice guarda su propia copia de cada documento. Borrar el archivo de origen no toca esa copia, así que el texto antiguo sigue respondiendo. Borra cada trozo del documento en el índice, y en cualquier caché de respuestas, en el mismo paso.
Un documento modificado es el mismo problema. Da a cada trozo una versión. Descarta los trozos más antiguos que la versión actual cuando se refresca el documento.
Un error frecuente
Advertencia
Mucha gente cree que borrar el archivo de origen quita el texto de la búsqueda. El índice guardó una copia, así que el texto se sigue encontrando. Borra también en el índice y comprueba buscando una frase de la página borrada.
Escribe la búsqueda con permisos, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const entries = [' ' { id: \"e2\", doc: \"nominas\", groups: [\"personal\"], version: 1, text: \"primas y fechas de vacaciones para directivos\" },' ' { id: \"e4\", doc: \"turnos\", groups: [\"personal\"], version: 1, text: \"quién trabaja en vacaciones\" },' ' { id: \"e1\", doc: \"manual\", groups: [\"personal\", \"estudiantes\"], version: 2, text: \"fechas de las vacaciones del trimestre\" },' ' { id: \"e3\", doc: \"manual\", groups: [\"personal\", \"estudiantes\"], version: 1, text: \"fechas antiguas de vacaciones\" },' '];' 'const current = { manual: 2, nominas: 1, turnos: 1 };' 'const ana = { name: \"ana\", groups: [\"estudiantes\"] };' > access1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la búsqueda con permisos, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function allowed(e, user) { return e.groups.some(function (g) { return user.groups.includes(g); }); }' 'function score(e, q) { return q.filter(function (w) { return e.text.split(\" \").includes(w); }).length; }' 'function top(list, q, k) {' ' return list.filter(function (e) { return score(e, q) > 0; })' ' .sort(function (a, b) { return score(b, q) - score(a, q); })' ' .slice(0, k);' '}' 'function ids(list) { return list.map(function (e) { return e.id; }).join(\" \") || \"nada\"; }' >> access1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la búsqueda con permisos, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const q = [\"vacaciones\", \"fechas\"];' 'function mine(list) { return list.filter(function (e) { return allowed(e, ana); }); }' 'console.log(\"filtro después de los 2 primeros:\", ids(mine(top(entries, q, 2))));' 'console.log(\"filtro antes de los 2 primeros:\", ids(top(mine(entries), q, 2)));' 'const fresh = entries.filter(function (e) { return e.version >= current[e.doc]; });' 'console.log(\"y con las copias caducadas fuera:\", ids(top(mine(fresh), q, 2)));' 'const left = entries.filter(function (e) { return e.doc === \"manual\" ? false : true; });' 'console.log(\"tras borrar el manual, Ana encuentra:\", ids(top(mine(left), q, 2)));' >> access1.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecuta y compara los filtros
docker exec -w /home/node/project agent node access1.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Esto es un sustituto
El índice es una lista de cuatro entradas y una persona es un nombre con grupos. Un sistema real filtra dentro de su motor de búsqueda, según la cuenta con sesión iniciada. Un borrado es una llamada real a ese motor.
El Run no llama a ningún modelo. La regla es la misma: filtrar primero, borrar en todas partes.
Lo que imprime el Run
| Línea | Resultado |
|---|---|
| filtro después de los 2 primeros | e1 |
| filtro antes de los 2 primeros | e1 e3 |
| y con las copias caducadas fuera | e1 |
| tras borrar el manual, Ana encuentra | nada |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.