我有以下
post
文件:
post = {"_id": "postID1", "userID": "userID1", "likeNum": 10, "url": "anyUrl"}
我有一个疑问:
posts_collection.find({"userID": {"$nin": ["uid1", "uid2"]}, "_id": {"$nin": ["postID1", "postID2"]}}).sort("likeNum", DESCENDING).limit(30).explain()
还有我的聚合管道:
pipeline = [
{"$match":{"userID": {"$nin": ["uid1", "uid2"]}, "_id": {"$nin": ["postID1", "postID2"]}}},
{"$sort": {"likeNum": -1}},
{"$group": {"_id": "$userID", "posts": {"$firstN": {"input": "$$ROOT", "n": 2}}}},
{"$unwind": "$posts"},
{"$replaceWith": "$posts"},
{"$sort": {"likeNum": -1}},
{"$limit": 30}
]
posts_collection.aggregate(pipeline)
我建立了一个索引
likeNum: -1
和另一个复合索引 userID: 1, _id: 1, likeNum: -1
explain()
方法始终显示它适用于likeNum: -1
并执行集合扫描。
我的聚合管道
explained
输出也在我的 MongoDB Atlas 仪表板的查询分析器中显示相同的信息。
是否是因为
$nin
内存中的排序性能低于集合扫描?还是有其他原因?
注意:有时查询可能只有
userID
过滤器而没有 _id
以及相反的(_id
没有 userID
),或者没有这些过滤器(在这种情况下我理解 likeNum: -1
) .
如果这有助于理解该行为,我在该集合中有 10k 个文档。
您有一个条件
{ _id: "$nin": ["postID1", "postID2"]}
,这意味着您将选择 all,但 2 个文档。在这种情况下,使用索引没有多大意义,因为您需要读取几乎整个索引以及文档中的几乎所有数据。
仅读取数据并跳过索引时,查询速度更快。