【问题标题】:MongoDB Aggregate Array with Two Fields具有两个字段的 MongoDB 聚合数组
【发布时间】:2015-05-14 23:09:40
【问题描述】:

我有以下架构的车辆集合,所有文章都只是一般产品(不包括子产品):

{
    "_id" : ObjectId("554995ac3d77c8320f2f1d2e"),
    "model" : "ILX",
    "year" : 2015,
    "make" : "Acura",
    "motor" : {
        "cylinder" : 4,
        "liters" : "1.5"
    },
    "products" : [
        ObjectId("554f92433d77c803836fefe3"),
        ...
    ]
}

我有产品集合,其中一些是与仓库sku相关的通用产品,一些产品是适合多个通用产品的“子”产品,这些子产品也与仓库sku相关:

一般产品

{
  "_id" : ObjectId("554b9f223d77c810e8915539"),
  "brand" : "Airtex",
  "product" : "E7113M",
"type" : "Fuel Pump",
"warehouse_sku" : [
    "1_5551536f3d77c870fc388a04",
    "2_55515e163d77c870fc38b00a"
]
}

子产品

{
    "_id" : ObjectId("55524d0c3d77c8ba9cb2d9fd"),
    "brand" : "Performance",
    "product" : "P41K",
    "type" : "Repuesto Bomba Gasolina",
    "general_products" : [
        ObjectId("554b9f223d77c810e8915539"),
        ObjectId("554b9f123d77c810e891552f")
    ],
    "warehouse_sku" : [
        "1_555411043d77c8066b3b6720",
        "2_555411073d77c8066b3b6728"
    ]
}

我的问题是获取符合以下模式的warehouse_sku 的一般产品列表(子产品中的_id 和general_products):1_

我创建了一个具有以下结构的聚合查询:

list_products = db.getCollection('products').aggregate([
...  {$match: {warehouse_sku: /^1\_/}},
...  {$group: { "_id": "$_id" } }
... ])

那个查询成功地给了我一个结果:

{ "_id" : ObjectId("55524d0c3d77c8ba9cb2d9fd") }
{ "_id" : ObjectId("554b9f223d77c810e8915539") }

但我需要获取通用产品列表,以便可以在车辆集合中使用 $in。

list_products = [ ObjectId("55524d0c3d77c8ba9cb2d9fd"), ObjectId("554b9f223d77c810e8915539")] 

示例:db.vehicles.find({products:{$in: list_products}})

这最后一个查询我无法实现。

【问题讨论】:

    标签: arrays mongodb mongodb-query


    【解决方案1】:

    使用聚合游标的map()方法返回一个ObjectIds数组,如下:

    var pipeline = [
        {$match: {warehouse_sku: /^1\_/}},
        {$group: { "_id": "$_id" } }
    ],
    list_products = db.getCollection('products')
                      .aggregate(pipeline)
                      .map(function(doc){ return doc._id });
    

    find() 光标的 map() 也可以在这里工作:

    var query = {'warehouse_sku': /^1\_/},
        list_products = db.getCollection('products')
                          .find(query)
                          .map(function(doc){ return doc._id });
    

    更新

    在 pymongo 中,您可以将 lambda 函数与 map 函数一起使用。因为 map 期望传入一个函数,所以它也恰好是 lambda 经常出现的地方之一:

    import re
    regx = re.compile("^1\_", re.IGNORECASE)
    products_cursor = db.products.find({"warehouse_sku": regx})
    list_products = list(map((lambda doc: doc["_id"]), products_cursor))
    

    【讨论】:

    • 太棒了,它给了我结果,是否有可能在不使用地图的情况下获得相同的结果?...我正在使用 PyMongo
    • @technology_dreamer 是的,有可能,请查看我更新的答案。虽然我还没有测试过,但它应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 2014-12-01
    • 2013-03-19
    • 1970-01-01
    • 2020-12-10
    • 2020-12-08
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    相关资源
    最近更新 更多