gpt4 book ai didi

MongoDB按二级查找表排序

转载 作者:IT老高 更新时间:2023-10-28 13:27:56 25 4
gpt4 key购买 nike

我有一个约会应用程序,我将所有潜在的 Match 对象存储在 MongoDB 中(当用户向左或向右滑动时会发生 Match 对象):

{
uid1: <userid1>,
uid2: <userid2>,

uid1action: <L|R|E> (left/right/empty, based what the user1 has done),
uid2action: <L|R|E> (left/right/empty, based what the user2 has done),
}

现在是我的问题。当我向 user1 显示潜在用户的个人资料时,我会考虑所有已经喜欢 user1 的人(因为我优先考虑这些个人资料):

var likedQuery = Parse.Query.or(new Parse.Query("Match")
.equalTo("uid1", userId)
.equalTo("u2action", "L")
.equalTo("u1action", "E") // user1 has not done anything
.select("uid2")
.limit(paginationLimit);

现在很好,一切正常。我现在还希望根据每个用户的点赞数(受欢迎程度)来对 LikedQuery 进行排序。

说这些是喜欢user1的以下用户:

保罗(保罗本人有 50 个人像他一样)

Logan(Logan 被 20 人点赞)

迈克尔(迈克尔被 80 人点赞),

我们希望对所有这些人进行排序,以便 Michael 成为 user1 看到的第一个个人资料。

现在我的问题是,我将如何使用 mongoDB?在 SQL 中这很简单,只需做一个表 JOIN,使用 SUM() 和 COUNT() 按该表排序,并确保您有必要的索引。

在 mongoDB 中,我看到如何做到这一点的唯一方法是在每个 Match 对象上都有一个 uid2likes (将对其进行排序)字段,该字段将由 cron 作业递增,但那是荒谬且无法扩展。

我的问题更多是关于如何以可扩展的方式做到这一点。

最佳答案

您可以在 3.4 中使用以下聚合查询。

这里的想法是$match所有喜欢user1的用户都喜欢自己$lookup获取所有喜欢user1的用户。

$group$sort按 count desc 对匹配项进行排序。

$limit限制匹配的用户。

db.colname.aggregate([
{"$match":{"uid1":userID,"uid2action":"L","uid1action":"E"}},
{"$lookup":{
"from":colname,
"localField":"uid2",
"foreignField":"uid1",
"as":"uid2likes"
}},
{"$unwind":"$uid2likes"},
{"$match":{"uid2likes.uid2action":"L"}},
{"$group":{
"_id":{"uid1":"$uid1","uid2":"$uid2"},
"uid2likecount":{"$sum":1}
}},
{"$sort":{"uid2likecount":-1}},
{"$limit":paginationLimit}
])

几个笔记

使用 $lookup + $unwind + $match 很重要在 3.4 中优化为通过移动查询谓词 $match 运行里面 $lookup .更多 here

您可以使用现有索引(假设您在 uid1 上有一个)进行初始匹配和查找匹配。

还可以尝试在 uid2action 上添加索引,看看它是否被 $lookup 拾取+ $match阶段。更多 here here

添加索引:

db.colname.createIndex( { uid1: 1 } )
db.colname.createIndex( { uid2action: 1 } )

衡量指标使用:

db.colname.aggregate([{$indexStats: {}}, {$project: {key: 0, host: 0}}]).pretty();

解释查询:

db.colname.explain("executionStats").aggregate(above pipeline);

您可以在索引之间交替并检查执行统计信息以查看索引是如何被拾取的。也尝试复合索引。

使用 3.6 可以稍微清理一下查询。

db.colname.aggregate([
{"$match":{"uid1":userID,"uid2action":"L","uid1action":"E"}},
{"$lookup":{
"from":colname,
"let":{"uid2":"$uid2"},
"pipeline":[
{"$match":{"$expr":{"$eq":["$uid1","$$uid2"]},"uid2action":"L"}},
{"$count":"count"}
],
"as":"uid2likes"
}},
{"$unwind":"$uid2likes"},
{"$sort":{"uid2likes.count":-1}},
{"$limit":paginationLimit}
])

关于MongoDB按二级查找表排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53053567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com