如何从mongo管道检索每个单个数组元素? [英] How to retrieve each single array element from mongo pipeline?
问题描述
我们假设这是样例文档在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
convertmonths
object to array$unwind
deconstruct months array$unwind
deconstructtransactions
array and provide index fieldindex
$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屋!