Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在EmbeddedDocumentList中匹配EmbeddedDocument_Python_Django_Mongodb_Mongoengine - Fatal编程技术网

Python 在EmbeddedDocumentList中匹配EmbeddedDocument

Python 在EmbeddedDocumentList中匹配EmbeddedDocument,python,django,mongodb,mongoengine,Python,Django,Mongodb,Mongoengine,所以我有这个测试数据,比如mongo,Cart模型: { "_id" : ObjectId("55eb513c516ddc8fa6e68886"), "user" : ObjectId("55e3f236516ddc78296968be"), "items" : [ { "item" : ObjectId("55eb10b8516ddc7508dba7c2"), "quantity" : 1,

所以我有这个测试数据,比如mongo,Cart模型:

{
"_id" : ObjectId("55eb513c516ddc8fa6e68886"),
    "user" : ObjectId("55e3f236516ddc78296968be"),
    "items" : [
        {
            "item" : ObjectId("55eb10b8516ddc7508dba7c2"),
            "quantity" : 1,
            "added_date" : ISODate("2015-09-05T20:32:16.527Z"),
            "coupons" : ObjectId("55eb10cd516ddc751d3d5e25"),
            "order_type" : [
                "in_store",
                "curbside"
            ]
        },
        {
            "item" : ObjectId("55eb10b8516ddc7508dba7cc"),
            "quantity" : 1,
            "added_date" : ISODate("2015-09-05T20:32:16.527Z"),
            "coupons" : ObjectId("55eb10cd516ddc751d3d5e25")
        },
        {
            "item" : ObjectId("55eb10b8516ddc7508dba7c8"),
            "quantity" : 1,
            "added_date" : ISODate("2015-09-05T20:32:16.527Z"),
            "coupons" : ObjectId("55eb10cd516ddc751d3d5e25")
        }
    ]
}
以下是我的模型:

class CartItem(mongoengine.EmbeddedDocument):
    item = mongoengine.ReferenceField('Item')
    quantity = mongoengine.IntField()
    added_date = mongoengine.DateTimeField( default=timezone.now() )
    coupons = mongoengine.ReferenceField('Coupon')
    order_type = mongoengine.ListField(mongoengine.StringField(choices=ORDER_TYPE_CHOICES))

class Cart(mongoengine.Document):
    user = mongoengine.ReferenceField('User')
    items = mongoengine.EmbeddedDocumentListField(CartItem)
    savings = mongoengine.DecimalField(precision=2, default=0)
现在,我希望能够获得CartItems,例如,这些CartItems只有的订单类型“in\u store”。所以我是这样说的:

cart = Cart.objects.filter(id="id")
items = cart.items
curbside_items = items.filter(order_type="curbside")
这不会返回任何内容。所以我试着这样做:

curbside_items = items.filter(order_type__math="curbside")
但这并没有给我任何回报。所以我的问题是如何在mongoengine中做到这一点。谢谢

MongoEngine使用for属性转换为MongoDB查询的形式。因此,您要查找的属性的“父级”是“项”,这意味着您引用了完整的路径,如下所示:

Cart.objects.filter(items__order_type="in_store")
其中文档在
数组中包含作为
订单类型
条目的“in_store”。请注意,这将返回“整个文档”,而不仅仅是匹配的条目。在response中还有其他处理方法

一种方法是使用底层pymongo驱动程序获得“原始”结果:

Cart._get_collection().find(
    { "items.order_type": "in_store" },
    { "items.$": 1 }
)
它利用运算符仅返回匹配的数组元素

或者对于“多重”匹配,则需要
.aggregate()

或者通过
$filter
在未来的版本中更具意义:

Cart._get_collection().aggregate([
    { "$match": {
        "items.order_type": "in_store"
    }},
    { "$project": {
        "items": {
            "$filter": {
                "input": "$items",
                "as": "el",
                "cond": { "$eq": [ "$$el.order_type", "in_store" ] }
            }
        }
    }}
])

“djangoesque”行中的标准mongoengine查询不支持此类操作,只返回未修改的整个文档。对于
$slice
来说是一个例外,这里有一个选项,可以执行与本机MongoDB对应的操作。

这让我得到了cart,但我想得到CartItem。我更新了帖子来表达我的意思。谢谢@布伦登:你没有真正理解我说的话,是吗?Mongoengine不支持mongodb查询通常提供的那种“投影”。如果您只想获取“匹配项”,那么您需要在代码中完成,因为mongoengine不会仅从数组“only”中检索匹配项。它需要文档中存在的整个数组。或者您可以改为使用“原始”查询,直接从底层pymongo驱动程序检索基本python对象。@Brenden1995阅读上面的内容怎么样。有足够多的证据来澄清每一个案例。
Cart._get_collection().aggregate([
    { "$match": {
        "items.order_type": "in_store"
    }},
    { "$project": {
        "items": {
            "$filter": {
                "input": "$items",
                "as": "el",
                "cond": { "$eq": [ "$$el.order_type", "in_store" ] }
            }
        }
    }}
])