
MongoDB Atlas Vector Search permite búsquedas de similitud eficientes basadas en representaciones vectoriales. Esto es particularmente beneficioso cuando se trabaja con datos no estructurados como texto, imágenes o audio, donde las búsquedas tradicionales basadas en palabras clave pueden quedarse cortas.
Ventajas clave:
Integración con OpenFGA:
Cuando se combina con OpenFGA, MongoDB Atlas Vector Search proporciona una poderosa solución para el acceso seguro de documentos. Puede usar la búsqueda de vectores para recuperar documentos relevantes en función de su contenido, y luego aplicar las reglas de control de acceso de OpenFGA para garantizar que solo los usuarios autorizados puedan ver los resultados.
Ejemplo:
Imagine un sistema de administración de documentos donde los usuarios pueden buscar documentos basados en su contenido. Al usar la búsqueda de vector Atlas MongoDB, puede recuperar eficientemente documentos que sean semánticamente similares a la consulta del usuario. OpenFGA se puede usar para hacer cumplir el control de acceso, asegurando que los usuarios solo vean documentos que están autorizados para ver.
OpenFGA es una plataforma de autorización de código abierto diseñada para proporcionar un control de acceso de grano fino para aplicaciones nativas de nube. Ofrece una solución flexible y escalable para administrar los permisos de los usuarios y el acceso a los recursos.
OpenFGA opera en el concepto de tuplas . Una tupla representa un permiso, que consiste en un usuario, una relación (por ejemplo, "leer", "escribir") y un objeto (por ejemplo, un archivo, una base de datos). Las políticas se definen para especificar qué tuplas están permitidas o denegadas. Cuando un usuario intenta acceder a un recurso, OpenFGA evalúa la tupla correspondiente contra las políticas definidas para determinar si el acceso se otorga o se niega.
Tire de la imagen OpenFGA Docker:
docker pull openfga/openfgaEjecute el contenedor OpenFGA con puertos expuestos:
docker run -p 8080:8080 -p 3000:3000 openfga/openfga runTire de la imagen de Docker local de MongoDB Atlas:
docker pull mongodb/mongodb-atlas-localEjecute el contenedor local MongoDB Atlas:
docker run -p 27017:27017 mongodb/mongodb-atlas-localEsta sección lo guía a través de la creación de un índice de búsqueda vectorial para búsquedas de similitud eficientes dentro de los datos de OpenFGA.
Conéctese al clúster Atlas local usando mongosh :
mongosh " mongodb://localhost/demo?directConnection=true " Cambie a la base de datos demo (reemplace con el nombre de su base de datos real si es necesario):
use demo
Cree un índice de búsqueda vectorial llamado "vector_index" en el campo "Incrustaciones":
db . mdb_fga . createSearchIndex (
"vector_index" ,
"vectorSearch" , // index type
{
fields : [
{
"type" : "vector" ,
"numDimensions" : 1536 ,
"path" : "embeddings" ,
"similarity" : "cosine"
} ,
]
}
) ;Instalación de bibliotecas de Python requeridas
pip install asyncio requests pymongo unstructured openai Este comando instala todas las bibliotecas necesarias ( asyncio , requests , pymongo , unstructured y openai ) para ejecutar el código Python.
No estructurado: extraer significado de documentos
No estructurado le permite dividir los documentos de texto en unidades más pequeñas y más manejables. Imagine un trabajo de investigación: no estructurado puede dividirlo en secciones, párrafos o incluso oraciones, lo que hace que sea más fácil procesar y analizar. La biblioteca también ayuda a extraer entidades como nombres, fechas y ubicaciones, ayudando en la recuperación de la información.
OpenFGA: asegurar el acceso a los datos extraídos
Usted define políticas que rigen los permisos de los usuarios en función de condiciones específicas. Cuando un usuario intenta acceder a un documento o sus datos extraídos, OpenFGA evalúa el usuario y el documento correspondiente contra estas políticas, otorgando o negando el acceso.
MongoDB Atlas Vector Búsqueda: Encontrar documentos similares de manera eficiente
Imagine que está buscando un concepto específico dentro de una recopilación de documentos. Las búsquedas basadas en palabras clave pueden perder documentos relevantes que no contienen las palabras clave exactas. La búsqueda vectorial, sin embargo, analiza las representaciones vectoriales del contenido de documentos, lo que le permite encontrar documentos semánticamente similares, incluso si usan una redacción diferente.
El poder de combinar estas herramientas
Al integrar estas tres herramientas, crea un sistema de gestión de documentos robusto y seguro. Aquí está el flujo de trabajo:
add_tuple en OpenFGA La función add_tuple que vio en el fragmento de código juega un papel crucial en la gestión del control de acceso dentro de la aplicación MDB-OpenFGA. Interactúa con OpenFGA para otorgar un permiso de usuario para ver un recurso específico.
Aquí hay un desglose de cómo funciona add_tuple :
Argumentos:
USER : Esto representa al usuario para quien está otorgando permiso. El código lo formatea como "user:"+USER para consistencia dentro de OpenFGA.RESOURCE : Esto representa el recurso al que se le otorga acceso al usuario. En el ejemplo, está formateado como "doc:"+RESOURCE (suponiendo documentos).API Llamada:
/stores/{store_id}/write ). Este punto final se usa para escribir datos (tuplas) en la tienda OpenFGA.writes : Esta clave contiene un objeto que especifica las tuplas que se agregarán.tuple_keys : esta es una matriz que contiene los objetos de tupla que definen los permisos. Cada objeto de tupla tiene tres propiedades:user : la ID de usuario como está formateada anteriormente.relation : Esto define el tipo de permiso que se otorga. En este caso, está configurado en "viewer" para indicar acceso de lectura.object : la identificación de recursos como formateada anteriormente.authorization_model_id : esto especifica la ID del modelo de autorización que se utiliza en OpenFGA. Este modelo define las reglas de control de acceso que rigen cómo se evalúan las tuplas.Respuesta:
En esencia, add_tuple crea una nueva tupla en OpenFGA, afirmando que un usuario específico ( USER ) tiene el permiso para ver un recurso específico ( RESOURCE ). Esta tupla será utilizada por los mecanismos de control de acceso de OpenFGA para determinar si el usuario está autorizado para acceder al recurso durante las futuras solicitudes.
check_authorization en mdb-openfga La función check_authorization juega un papel vital en la aplicación MDB-OpenFGA. Es responsable de determinar si un usuario determinado tiene permiso para acceder a un recurso específico basado en las políticas de control de acceso definidas en OpenFGA.
Cómo funciona:
Argumentos:
tuple_key : este es un objeto JSON que representa una tupla. Una tupla, como saben, define un permiso. Normalmente contiene tres propiedades:user : la ID de usuario.relation : el tipo de permiso (por ejemplo, "Visor", "Editor").object : la identificación de recursos.API Llamada:
/stores/{store_id}/check . Este punto final se utiliza para evaluar una tupla contra el modelo de autorización definido.authorization_model_id : la ID del modelo de autorización que se utiliza.tuple_key : el objeto Tuple que desea verificar.Respuesta:
bool :true : el usuario tiene permiso.false : el usuario no tiene permiso. En esencia, check_authorization toma una tupla como entrada y consultas OpenFGA para determinar si el usuario especificado en la tupla puede realizar la acción (relación) en el recurso especificado (objeto).
Ejecutando la demostración
python3 demo.py
Starting FGA setup...
FGA setup response: {'code': 'write_failed_due_to_invalid_input', 'message': "cannot write a tuple which already exists: user: 'user:demo_user', relation: 'viewer', object: 'doc:demo.pdf': invalid write input"}
Clearing the db first...
Database cleared.
Starting PDF document partitioning...
PDF partitioning and database insertion completed successfully.
Waiting for index to be updated. This may take a few seconds...
Starting search tool...
Access Granted: User 'demo_user' has permission to read document 'demo.pdf'.
Access Denied: User 'demo_user-denyme' does not have permission to read document 'demo.pdf'.
import asyncio
import requests
import json
import pymongo
from unstructured . partition . auto import partition
from openai import AzureOpenAI
class FGA_MDB_DEMO :
def __init__ ( self , azure_endpoint , api_version , api_key , mongo_uri , fga_api_url , fga_store_id , fga_api_token , authorization_model_id , db_name , collection_name ):
self . az_client = AzureOpenAI ( azure_endpoint = azure_endpoint , api_version = api_version , api_key = api_key )
self . mongo_client = pymongo . MongoClient ( mongo_uri )
self . fga_api_url = fga_api_url
self . fga_store_id = fga_store_id
self . fga_api_token = fga_api_token
self . authorization_model_id = authorization_model_id
self . db_name = db_name
self . collection_name = collection_name
def generate_embeddings ( self , text , model = "" ):
return self . az_client . embeddings . create ( input = [ text ], model = model ). data [ 0 ]. embedding
def check_authorization ( self , tuple_key ):
url = f" { self . fga_api_url } /stores/ { self . fga_store_id } /check"
headers = {
"Authorization" : f"Bearer { self . fga_api_token } " ,
"content-type" : "application/json" ,
}
data = {
"authorization_model_id" : self . authorization_model_id ,
"tuple_key" : tuple_key
}
response = requests . post ( url , headers = headers , data = json . dumps ( data ))
return response . json ()
def add_tuple ( self , USER , RESOURCE ):
url = f" { self . fga_api_url } /stores/ { self . fga_store_id } /write"
headers = {
"Authorization" : f"Bearer { self . fga_api_token } " ,
"content-type" : "application/json" ,
}
data = {
"writes" : {
"tuple_keys" : [
{
"user" : "user:" + USER ,
"relation" : "viewer" ,
"object" : "doc:" + RESOURCE
}
]
},
"authorization_model_id" : self . authorization_model_id
}
response = requests . post ( url , headers = headers , data = json . dumps ( data ))
return response . json ()
def search_tool ( self , text , USER_ID ):
response = self . mongo_client [ self . db_name ][ self . collection_name ]. aggregate ([
{
"$vectorSearch" : {
"index" : "vector_index" ,
"queryVector" : self . az_client . embeddings . create ( model = "text-embedding-ada-002" , input = text ). data [ 0 ]. embedding ,
"path" : "embeddings" ,
"limit" : 5 ,
"numCandidates" : 30
}
}, { "$project" :{ "_id" : 0 , "embeddings" : 0 , "metadata" : 0 }}
])
for doc in response :
tuple_key = { "user" : "user:" + USER_ID , "relation" : "viewer" , "object" : "doc:" + doc [ "source" ]}
response = self . check_authorization ( tuple_key )
if response [ 'allowed' ]:
print ( f"Access Granted: User ' { USER_ID } ' has permission to read document ' { doc [ 'source' ] } '." )
else :
print ( f"Access Denied: User ' { USER_ID } ' does not have permission to read document ' { doc [ 'source' ] } '." )
def partition_pdf ( self , resource ):
mdb_db = self . mongo_client [ self . db_name ]
mdb_collection = mdb_db [ self . collection_name ]
print ( "Clearing the db first..." )
mdb_collection . delete_many ({})
print ( "Database cleared." )
print ( "Starting PDF document partitioning..." )
elements = partition ( resource )
for element in elements :
mdb_collection . insert_one ({
"text" : str ( element . text ),
"embeddings" : self . generate_embeddings ( str ( element . text ), "text-embedding-ada-002" ),
"metadata" : {
"raw_element" : element . to_dict (),
},
"source" : resource
})
print ( "PDF partitioning and database insertion completed successfully." )
def fga_setup ( self , user , resource ):
response = self . add_tuple ( user , resource )
print ( f"FGA setup response: { response } " )
async def main ( self , user , resource ):
print ( "Starting FGA setup..." )
self . fga_setup ( user , resource )
self . partition_pdf ( resource )
print ( "Waiting for index to be updated. This may take a few seconds..." )
await asyncio . sleep ( 15 )
print ( "Starting search tool..." )
self . search_tool ( "test" , user )
self . search_tool ( "test" , user + "-denyme" )
print ( "Process completed successfully." )
if __name__ == "__main__" :
fga_mdb_demo = FGA_MDB_DEMO (
azure_endpoint = "" ,
api_version = "2024-04-01-preview" ,
api_key = "" ,
mongo_uri = "mongodb://localhost:27017/demo?directConnection=true" ,
fga_api_url = 'http://localhost:8080' ,
fga_store_id = '01J8VP1HYCHN459VT76DQG0W2R' ,
fga_api_token = '' ,
authorization_model_id = '01J8VP3BMPZNFJ480G5ZNF3H0C' ,
db_name = "demo" ,
collection_name = "mdb_fga"
)
asyncio . run ( fga_mdb_demo . main ( "demo_user" , "demo.pdf" ))