我有一个包含两个表的SQLite数据库:
Objects:
object_id int,
name varchar(50)
Values:
key char(12),
value int,
object_id int
如您所见,每个对象都包含一个键值对列表。此列表通常包含10到60个条目。 (key,object_id)的组合在值表中是唯一的。
然后我从用户那里获得键值对的列表,并希望在数据库中搜索最相似的对象。在大多数情况下,用户提供的对象不会直接匹配我的数据库中的任何对象。
相似性意味着两个对象的键列表几乎相等,并且这些键的值相似(在大多数情况下,值也不相等)。该列表可以是可变长度。
请考虑以下列表:
A = { a: 10, b: 20, c: 30 }
B = { a: 11, c: 80, d: 90 }
C = { c: 70, d: 89, e: 40, f: 100 }
D = { c: 65, d: 80, e: 41 }
A和B都包含 a 和 c 键,而 b 和 d 仅包含在一个他们因此,如果我们只查看键,则相似度为0.5。 A和D只有 c , a , b , d 和 e 仅包含在一个列表中。所以他们不会非常相似。
在下一步中,我必须查找匹配键的值。因此,在A和B的示例中,必须比较键 a 和 c 的值。 a 非常相似,而 c 不是很好的匹配。
是否可以直接使用SQLite进行搜索?如果没有,那么搜索的最佳方式/算法是什么?搜索应该尽可能快,但不应该消耗太多的计算能力/内存,因为我在移动设备上这样做。
我非常感谢有关此主题的任何帮助,链接或资源。
答案 0 :(得分:1)
如果我正确理解,你想要将所有记录与来自用户输入的固定记录集进行比较(假设它是一个与Values
具有相同结构的表)=> O(n * m 1 * m 2 ) (其中n =对象编号,n * m 1 =值中的记录数,m 2 =用户输入中的键) - 如果m 1,2 ,则基本为O(n)常数因素:
select
v1.object_id,
count(distinct v1.key) cnt_obj_keys,
count(distinct v2.key) cnt_usr_keys, --replace with a constant from outside code
count(case
when v1.key = v2.key
then 1
end) cnt_similar_keys,
count(case
when v1.key = v2.key and v1.value = v2.value
then 1
end) cnt_similar_values
from values v1
cross join values_from_user v2
group by v1.object_id
;
然后你只需要为每个对象使用一个公式,即 O(n),来计算用于对对象进行排序并获取它们的第一个x
的未指定索引 - 例如:
order by
cnt_similar_keys / (cnt_obj_keys + cnt_usr_keys - cnt_similar_keys),
cnt_similar_values / cnt_similar_keys