现在我有两个PyMODM模型:
class PlaylistTrack(MongoModel):
post = fields.ReferenceField(Post, primary_key=True)
playlist_position = fields.IntegerField() # Uses zero-indexing
class Post(MongoModel):
reddit_post_id = fields.CharField(required=True, primary_key=True)
subreddit = fields.CharField()
exists_in_playlist = fields.BooleanField()
#
# ... some more irrelevant fields
#
如您所见,PlaylistTrack
模型包含对Post
模型的引用id
在我的代码中,我希望获得与某个Post字段和PlayTrack字段匹配的所有PlayTrack,如下所示:
# This is psuedocode, not actually valid PyMODM syntax
tracks = PlaylistTrack.objects.raw(
{"post.subreddit": subreddit_name,
"playlist_position": {"$gt": pos_in_spotify, "$lte": new_pos}}
)
PyMODM不允许我这样做,因为post不是嵌入式文档,但它是另一篇文章的引用字段。在研究文档时,我发现mongodbaggregate()
管道与$lookup
操作符耦合将执行左外连接,从而允许我执行类似的操作:
playlisttracks = PlaylistTrack.objects.all().aggregate(
{
"$lookup": {
"from": "post",
"localField": "_id",
"foreignField": "_id",
"as": "playlisttrack_post"
}
},
{
"$match": {
"playlisttrack_post.subreddit": self.subreddit_name,
"playlisttrack_post.exists_in_playlist": True
}
},
{
"$sort": {"playlist_position": pymongo.ASCENDING}
})
此的问题是,它返回PyMongo CommandCursor类型,而不是PyMODM QuerySet类型。这意味着我不能使用QuerySet类方法(这对于PyMODM模型来说更自然),而是必须将所有内容都转换为PyMongo,这有点像是违背了使用PyMODM的目的和不自然
因此,相反,我做这件事是作为一个黑客的解决办法
posts = Post.objects.raw({"$and":
[{"subreddit": self.subreddit_name},
{"exists_in_playlist": True}]})
post_ids = [p.reddit_post_id for p in posts]
# Get all tracks in playlist in order
playlisttracks = PlaylistTrack.objects \
.raw({"_id": {"$in": post_ids}}) \
.order_by([("playlist_position", pymongo.ASCENDING)]
我没有使用$lookup
进行连接,而是找到我想要的帖子,并将其作为查询的一部分
这确保返回的对象是PyMODM QuerySet对象
有没有更好的方法使用原生PyMODM语法来实现这一点?我是否误解了如何使用PyMongo/PyMODM,因为它们是预期使用的
我知道在NoSQL中使用连接有点棘手,但我还是觉得一定有比这更好的方法
目前没有回答
相关问题 更多 >
编程相关推荐