
A Pesquisa de Vector Atlas do MongoDB permite pesquisas eficientes de similaridade com base em representações vetoriais. Isso é particularmente benéfico ao trabalhar com dados não estruturados, como texto, imagens ou áudio, onde as pesquisas tradicionais baseadas em palavras-chave podem ficar aquém.
Principais vantagens:
Integração com OpenFGA:
Quando combinado com o OpenFGA, a pesquisa vetorial do MongoDB Atlas fornece uma solução poderosa para o acesso seguro de documentos. Você pode usar a pesquisa vetorial para recuperar documentos relevantes com base em seu conteúdo e, em seguida, aplicar as regras de controle de acesso do OpenFGA para garantir que apenas usuários autorizados possam visualizar os resultados.
Exemplo:
Imagine um sistema de gerenciamento de documentos em que os usuários possam pesquisar documentos com base em seu conteúdo. Ao usar a pesquisa vetorial do MongoDB Atlas, você pode recuperar com eficiência documentos que são semanticamente semelhantes à consulta do usuário. O OpenFGA pode ser usado para aplicar o controle de acesso, garantindo que os usuários vejam apenas documentos que estão autorizados a visualizar.
O OpenFGA é uma plataforma de autorização de código aberto projetado para fornecer controle de acesso de granulação fina para aplicativos nativos da nuvem. Oferece uma solução flexível e escalável para gerenciar permissões de usuário e acesso a recursos.
O OpenFGA opera com o conceito de tuplas . Uma tupla representa uma permissão, composta por um usuário, uma relação (por exemplo, "leitura", "write") e um objeto (por exemplo, um arquivo, um banco de dados). As políticas são definidas para especificar quais tuplas são permitidas ou negadas. Quando um usuário tenta acessar um recurso, o OpenFGA avalia a tupla correspondente em relação às políticas definidas para determinar se o acesso é concedido ou negado.
Puxe a imagem do Docker Openfga:
docker pull openfga/openfgaExecute o contêiner OpenFGA com portas expostas:
docker run -p 8080:8080 -p 3000:3000 openfga/openfga runPuxe a imagem do Docker local do MongoDB Atlas:
docker pull mongodb/mongodb-atlas-localExecute o contêiner local do MongoDB Atlas:
docker run -p 27017:27017 mongodb/mongodb-atlas-localEsta seção o guia através da criação de um índice de pesquisa vetorial para pesquisas eficientes de similaridade nos dados do OpenFGA.
Conecte -se ao cluster do Atlas local usando mongosh :
mongosh " mongodb://localhost/demo?directConnection=true " Alterne para o banco de dados demo (substitua pelo nome real do banco de dados, se necessário):
use demo
Crie um índice de pesquisa vetorial chamado "Vector_index" no campo "Embeddings":
db . mdb_fga . createSearchIndex (
"vector_index" ,
"vectorSearch" , // index type
{
fields : [
{
"type" : "vector" ,
"numDimensions" : 1536 ,
"path" : "embeddings" ,
"similarity" : "cosine"
} ,
]
}
) ;Instalando as bibliotecas Python necessárias
pip install asyncio requests pymongo unstructured openai Este comando instala todas as bibliotecas necessárias ( asyncio , requests , pymongo , unstructured e openai ) para executar o código Python.
Não estruturado: Extraindo o significado dos documentos
Não estruturou o capacita você a dividir os documentos de texto em unidades menores e mais gerenciáveis. Imagine um artigo de pesquisa: não estruturado, pode dividi -lo em seções, parágrafos ou até sentenças, facilitando o processamento e a análise. A biblioteca também ajuda a extrair entidades como nomes, datas e locais, ajudando na recuperação de informações.
OpenFGA: garantir o acesso a dados extraídos
Você define políticas que governam as permissões de usuário com base em condições específicas. Quando um usuário tenta acessar um documento ou seus dados extraídos, o OpenFGA avalia o usuário correspondente e o documento em relação a essas políticas, concedendo ou negando acesso.
Pesquisa vetorial do Atlas MongoDB: Encontrar documentos semelhantes com eficiência
Imagine que você está procurando um conceito específico em uma coleção de documentos. Pesquisas baseadas em palavras-chave podem perder documentos relevantes que não contêm as palavras-chave exatas. A pesquisa de vetores, no entanto, analisa as representações vetoriais do conteúdo do documento, permitindo que você encontre documentos semanticamente semelhantes, mesmo que eles usem uma redação diferente.
O poder de combinar essas ferramentas
Ao integrar essas três ferramentas, você cria um sistema de gerenciamento de documentos robusto e seguro. Aqui está o fluxo de trabalho:
add_tuple no Openfga A função add_tuple que você viu no snippet de código desempenha um papel crucial no gerenciamento do controle de acesso no aplicativo MDB-Openfga. Ele interage com o OpenFGA para conceder permissão a um usuário para visualizar um recurso específico.
Aqui está um colapso de como add_tuple funciona:
Argumentos:
USER : Isso representa o usuário para quem você está concedendo permissão. O código o forma como "user:"+USER para consistência no OpenFGA.RESOURCE : isso representa o recurso ao qual o usuário está recebendo acesso. No exemplo, ele é formatado como "doc:"+RESOURCE (assumindo documentos).Chamada de API:
/stores/{store_id}/write ). Esse terminal é usado para escrever dados (tuplas) na loja OpenFGA.writes : essa chave mantém um objeto que especifica as tuplas a serem adicionadas.tuple_keys : Esta é uma matriz que contém os objetos de tupla que definem as permissões. Cada objeto de tupla tem três propriedades:user : o ID do usuário como formatado anteriormente.relation : isso define o tipo de permissão que está sendo concedida. Nesse caso, ele está definido como "viewer" para indicar acesso de leitura.object : o ID do recurso como formatado anteriormente.authorization_model_id : Isso especifica o ID do modelo de autorização usado no OpenFGA. Este modelo define as regras de controle de acesso que governam como as tuplas são avaliadas.Resposta:
Em essência, add_tuple cria uma nova tupla no OpenFGA, afirmando que um usuário específico ( USER ) tem a permissão para visualizar um recurso específico ( RESOURCE ). Esta tupla será usada pelos mecanismos de controle de acesso da OpenFGA para determinar se o usuário está autorizado a acessar o recurso durante solicitações futuras.
check_authorization em MDB-Openfga A função check_authorization desempenha um papel vital no aplicativo MDB-Openfga. É responsável por determinar se um determinado usuário tem permissão para acessar um recurso específico com base nas políticas de controle de acesso definidas no OpenFGA.
Como funciona:
Argumentos:
tuple_key : Este é um objeto JSON que representa uma tupla. Uma tupla, como você sabe, define uma permissão. Normalmente contém três propriedades:user : o ID do usuário.relation : o tipo de permissão (por exemplo, "Visualizador", "Editor").object : o ID do recurso.Chamada de API:
/stores/{store_id}/check . Esse terminal é usado para avaliar uma tupla contra o modelo de autorização definido.authorization_model_id : o ID do modelo de autorização que está sendo usado.tuple_key : o objeto de tupla que você deseja verificar.Resposta:
bool :true : o usuário tem permissão.false : o usuário não tem permissão. Em essência, check_authorization toma uma tupla como entrada e consultas OpenFGA para determinar se o usuário especificado na tupla pode executar a ação (relação) no recurso especificado (objeto).
Executando a demonstração
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" ))