如何从mongo管道检索每个单个数组元素? [英] How to retrieve each single array element from mongo pipeline?

查看:58
本文介绍了如何从mongo管道检索每个单个数组元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们假设这是样例文档在mongo-db中的样子,

Let's assume that this is how a sample document looks like in mongo-db,

[
  {
    "_id": "1",
    "attrib_1": "value_1",
    "attrib_2": "value_2",
    "months": {
      "2": {
        "month": "2",
        "year": "2008",
        "transactions": [
          {
            "field_1": "val_1",
            "field_2": "val_2",
            
          },
          {
            "field_1": "val_4",
            "field_2": "val_5",
            "field_3": "val_6"
          },
          
        ]
      },
      "3": {
        "month": "3",
        "year": "2018",
        "transactions": [
          {
            "field_1": "val_7",
            "field_3": "val_9"
          },
          {
            "field_1": "val_10",
            "field_2": "val_11",
            
          },
          
        ]
      },
      
    }
  }
]

所需的输出是这样的(我只是在第2个月和第3个月中显示它)

The desired output is something like this, (I am just showing it for months 2 & 3)

<身体>
id 个月 year field_1 field_2 field_3
1 2 2008 val_1 val_2
1 2 2008 val_4 val_5 val_6
1 3 2018 val_7 val_9
1 3 2018 val_10 val_11

我的尝试:

我在Py-Mongo中尝试了类似的方法,

I tried something like this in Py-Mongo,

pipeline = [
    {
        # some filter logic here to filter data basically first
    },
    {
        "$addFields": {
            "latest": {
                "$map": {
                    "input": {
                        "$objectToArray": "$months",
                    },
                    "as": "obj",
                    "in": {
                        "all_field_1" : {"$ifNull" : ["$$obj.v.transactions.field_1", [""]]},
                        "all_field_2": {"$ifNull" : ["$$obj.v.transactions.field_2", [""]]},
                        "all_field_3": {"$ifNull" : ["$$obj.v.transactions.field_3", [""]]},
                        "all_months" : {"$ifNull" : ["$$obj.v.month", ""]},
                        "all_years" : {"$ifNull" : ["$$obj.v.year", ""]},
                    }
                }
            }
        }
    },
    {
        "$project": {
            "_id": 1,
            "months": "$latest.all_months",
            "year":  "$latest.all_years",
            "field_1": "$latest.all_field_1",
            "field_2": "$latest.all_field_2",
            "field_3": "$latest.all_field_3",

        }
    }
]

# and I executed it as
my_db.collection.aggregate(pipeline, allowDiskUse=True)

以上内容实际上是在携带数据,但实际上是在列表中.有没有办法在mongo本身中轻松地将它们排成一行?

The above is actually bring the data but it's bringing them in lists. Is there a way to easily bring them one each row in mongo itself?

以上内容通过这种方式带来数据

the above brings data in this way,

<身体>
id 个月 year field_1 field_2 field_3
1 ["2","3"] ["2008","2018"] [[["val_1","val_4"],["val_7","val_10&"]] [[["val_2","val_5"],[","val_11"]] [[","val_6"],["val_9","]]

非常感谢您提供宝贵的宝贵意见,以寻求相同和更好的方法!

Would highly appreciate your valuable inputs regarding the same and a better way to do the same as well!

感谢您的时间.

我的Mongo版本是3.4.6,我正在使用PyMongo作为驱动程序.您可以在 mongo-db-playground

My Mongo version is 3.4.6 and I am using PyMongo as my driver. You can see the query in action at mongo-db-playground

推荐答案

在聚合查询中进行所有处理可能不是一个好主意,您可以在客户端执行此操作,

This is might be bad idea to do all process in a aggregation query, you could do this in your client side,

我创建了一个查询,该查询很长,可能会导致海量数据中的性能问题,

I have created a query which is lengthy may cause performance issues in huge data,

  • $ objectToArray months 个对象转换为数组
  • $ unwind 解构月份数组
  • $ unwind 解构 transactions 数组并提供索引字段 index
  • $ group 通过 _id,年,月和索引,并从字段中的事务中获取第一个对象
  • $ project ,如果需要,您可以设计响应,否则,这是可选的,我已经在游乐场链接中添加了
  • $objectToArray convert months object to array
  • $unwind deconstruct months array
  • $unwind deconstruct transactions array and provide index field index
  • $group by _id, year, month and index, and get first object from transactions in fields
  • $project you can design your response if you want otherwise this is optional i have added in playground link
my_db.collection.aggregate([
  { # some filter logic here to filter data basically first },
  { $project: { months: { $objectToArray: "$months" } } },
  { $unwind: "$months" },
  {
    $unwind: {
      path: "$months.v.transactions",
      includeArrayIndex: "index"
    }
  },
  {
    $group: {
      _id: {
        _id: "$_id",
        year: "$months.v.year",
        month: "$months.v.month",
        index: "$index"
      },
      fields: { $first: "$months.v.transactions" }
    }
  }
], allowDiskUse=True);

游乐场

这篇关于如何从mongo管道检索每个单个数组元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆