仅在用户可以访问的文档中搜索数据的高效数据结构

问题描述

问题描述:

目标是在尊重文档级安全性的同时有效地从一组 JSON 文档中查询字符串,以便用户只能从他们有权访问的文档中检索数据。

假设我们有以下文件

文档document_1,没有限制:

{
    "id": "document_1","set_of_strings_1": [
        "the","quick","brown"
    ],"set_of_strings_2": [
        "fox","jumps","over",],"isPublic": true
}

文档 document_2,只能由 3 个用户访问:

{
    "id": "document_2","set_of_strings_1": [
        "the"
        "lazy"
    ],"set_of_strings_2": [
        "dog","isPublic": false,"allowed_users": [
        "Alice","Bob","Charlie"
    ]
}

现在假设用户 Bob(可以访问两个文档)进行以下查询

getStrings(
    user_id: "Bob",set_of_strings_id: "set_of_strings_1"
)

正确的响应应该是来自两个文档的 set_of_strings_1 的并集:

["the","brown","lazy"]

现在假设用户 Dave(只能访问 document_1)进行以下查询

getStrings(
    user_id: "Dave",set_of_strings_id: "set_of_strings_1"
)

正确的响应应该是来自 set_of_strings_1document_1

["the","brown"]

进一步优化是处理前缀标记。例如。用于查询

getStrings(
    user_id: "Bob",set_of_strings_id: "set_of_strings_1",token: "t"
)

正确的回答应该是:

["the"]

注意:空标记应该匹配所有字符串。

但是,我很高兴在检索字符串后执行简单的内存中前缀匹配。这里的瓶颈预计是文档的数量,而不是字符串的数量


我尝试过的:

方法 1:天真的方法

这里最简单的解决方案是:

  • 将所有文档放入 sql 数据库
  • 执行全表扫描以获取所有文档(我们可以拥有数百万个文档)
  • 遍历所有文档以找出用户权限
  • 过滤掉用户可以访问的文档集
  • 遍历过滤后的列表以获取所有字符串

这太慢了。

方法二:倒排指数

考虑的另一种方法是创建从用户到文档的倒排索引,例如

users documents_they_can_see
user_1 document_1,document_2,document_3
user_2 document_1
user_3 document_1,document_4

这将有效地为我们提供文档 ID,我们可以将其用于其他索引以构建字符串集。

如果下一步是天真地完成,它仍然涉及对用户能够访问的所有文档进行线性扫描。为避免这种情况,我们可以创建另一个倒排索引映射 document_id#set_of_strings_id 到相应的字符串集,然后我们只需取所有集的并集来获得结果,然后我们可以运行前缀匹配。然而,这涉及到大量集合的并集。

方法 3:缓存

将 redis 与以下数据模型结合使用:

key value
user_id#set_of_strings_id [String]

然后我们在内存中对从缓存中获取的字符串集执行前缀匹配。

我们希望这些数据是最新的,因此真实数据存储仍然需要高性能

我不想重新发明轮子。是否有数据结构或一些现成的系统可以完成我想要做的事情?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...