MongoDB, MongoEngine 中通过 EmbeddedDocument 获取 Document 对象

在 MongoDB 和 MongoEngine 中,使用 EmbeddedDocument 时可能会遇到需要通过 EmbeddedDocument 对象来获取其对应的 Document 对象的情况。例如,在以下代码中,我们定义了一个 EmbeddedDocument 类 ToySale,它具有 end_time 和 percentage 字段,并定义了一个属性 super_price,该属性可以根据 ToySale 中的字段值计算出 Toy 的价格。

from mongoengine import EmbeddedDocument, Document, FloatField, IntField
class ToySale(EmbeddedDocument):
    end_time = FloatField()
    percentage = IntField()

    @property
    def super_price(self):
        return self.toy.price - (self.percentage * self.toy.price / 100)

class Toy(Document)
    sale = EmbeddedDocumentField(ToySale)
    price = IntField()

在上述代码中,我们希望在 ToySale 的 super_price 属性中访问 Toy 的 price 字段。但是,在 MongoEngine 中,EmbeddedDocument 类没有类似 Django ORM 中的 ‘related_name’ 机制,因此我们无法直接通过 ToySale 对象来访问 Toy 的字段。
在这里插入图片描述

2、解决方案

解决方案一:通过 EmbeddedDocument 字段查询

我们可以通过 EmbeddedDocument 的字段来查询对应的 Document 对象。例如,如果我们知道 ToySale 的 end_time 字段的值,我们可以使用以下代码来查询 Toy 对象:

Toy.objects(sale__end_time=3.14)

如果我们知道 ToySale 的 percentage 字段的值,我们可以使用以下代码来查询 Toy 对象:

Toy.objects(sale__percentage=3)

如果我们知道 ToySale 的 end_time 和 percentage 字段的值,我们可以使用以下代码来查询 Toy 对象:

Toy.objects(sale__end_time=3.14, sale__percentage=3)

解决方案二:通过 EmbeddedDocument 对象查询

如果我们已经有一个 ToySale 对象,我们可以使用以下代码来查询对应的 Toy 对象:

Toy.objects(**{'sale__' + key: value 
               for key, value in toy_sale.to_mongo().items()
               if not key.startswith('_')})

或者,我们可以使用以下更简单的代码:

Toy.objects(sale=toy_sale)

代码示例:

from mongoengine import connect
import datetime

connect('mongodb://localhost:27017', db='test_database')

class ToySale(EmbeddedDocument):
    end_time = FloatField()
    percentage = IntField()

    @property
    def super_price(self):
        return self.toy.price - (self.percentage * self.toy.price / 100)

class Toy(Document)
    sale = EmbeddedDocumentField(ToySale)
    price = IntField()

toy1 = Toy(price=100)
toy1.sale = ToySale(end_time=datetime.datetime.now(), percentage=20)
toy1.save()

toy2 = Toy(price=200)
toy2.sale = ToySale(end_time=datetime.datetime.now(), percentage=10)
toy2.save()

# 查询 Toy 对象,其 sale.end_time 字段值为 datetime.datetime.now()
toys1 = Toy.objects(sale__end_time=datetime.datetime.now())
print(toys1)

# 查询 Toy 对象,其 sale.percentage 字段值为 10
toys2 = Toy.objects(sale__percentage=10)
print(toys2)

# 查询 Toy 对象,其 sale.end_time 字段值为 datetime.datetime.now() 且 sale.percentage 字段值为 10
toys3 = Toy.objects(sale__end_time=datetime.datetime.now(), sale__percentage=10)
print(toys3)

# 获取第一个 Toy 对象的 ToySale 对象
toy_sale = toy1.sale

# 通过 ToySale 对象查询 Toy 对象
toy = Toy.objects(sale=toy_sale)
print(toy)
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值