如何确定App互动集合中成员的存储顺序及查询逻辑?
如何设计互动关系集合的字段存储与查询逻辑?
我打算在App里创建一个interaction集合,用来存储用户之间的互动关系,比如屏蔽、点赞、关注这类行为。初步设计的Schema是这样的:
{ mem_1: user_id, mem_2: user_id, mem_1_blocked_mem_2: boolean, mem_2_blocked_mem_1: boolean, // 其他互动字段,比如mem_1_followed_mem_2等 }
现在遇到两个核心问题:
- 怎么确定把哪个用户的ID存到
mem_1,哪个存到mem_2? - 查询的时候,怎么准确识别这两个字段对应的用户关系?
一、确定mem_1和mem_2的存储规则
- 固定排序规则:用用户ID的字符串字典序或者数值大小来排序,把字典序更小(或数值更小)的ID存在
mem_1,更大的存在mem_2。这样不管是A和B互动,还是B和A互动,存储的mem_1和mem_2都是固定组合,避免出现重复文档(比如(A,B)和(B,A)各存一份)。
举个例子:如果用户ID是字符串,userA_id = "u_123",userB_id = "u_456",因为"u_123" < "u_456",所以mem_1 = "u_123",mem_2 = "u_456"。 - 按互动发起方区分:如果某些互动有明确发起方和接收方(比如关注、点赞),可以规定发起方存
mem_1,接收方存mem_2。但要注意,双向互动(比如互相屏蔽)得确保字段对应关系正确,而且可能会出现同一对用户的两份文档(比如A关注B存一份,B关注A再存一份),需要权衡存储冗余和查询效率。
二、查询时的识别逻辑
- 基于固定排序规则的查询:查询某用户X和Y的互动时,先对X和Y的ID做排序,确定哪个是
mem_1候选、哪个是mem_2候选,然后直接按这两个值查询文档。比如要查用户X和Y的屏蔽关系,先比较X和Y的ID,假设X的ID更小,就查{mem_1: X_id, mem_2: Y_id},然后从返回的文档里读取mem_1_blocked_mem_2(即X是否屏蔽Y)和mem_2_blocked_mem_1(即Y是否屏蔽X)。 - 基于发起方的查询:如果是按发起方存的,查询用户X发起的互动,直接查
{mem_1: X_id},就能拿到X对其他用户的所有互动(关注、点赞、屏蔽等);查询用户X收到的互动,查{mem_2: X_id},就能拿到其他用户对X的互动。如果要查X和Y的双向互动,需要同时查{mem_1: X_id, mem_2: Y_id}和{mem_1: Y_id, mem_2: X_id},或者提前在Schema里做处理避免重复。
额外优化建议
- 避免冗余字段:如果某些互动是单向的(比如点赞,通常是A点赞B,很少有反向点赞逻辑),可以不用存反向字段,只保留发起方到接收方的字段即可,减少Schema复杂度。
- 建立复合索引:不管用哪种规则,都要给
mem_1和mem_2建立复合索引,比如执行db.interactions.createIndex({mem_1: 1, mem_2: 1}),这样查询一对用户的互动时速度会更快。
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

