Json Efficient MongoDB查询以从一个集合中获取报告并插入到另一个集合中
我想咨询一下如何使用MongoDB解决特定任务。我会尽我最大的努力解释整个画面,这样就不会出现XY问题。这将是一个有点长,所以我感谢所有谁得到的主题结束。我有一个包含报告的集合(我们称之为Json Efficient MongoDB查询以从一个集合中获取报告并插入到另一个集合中,json,mongodb,mongodb-query,aggregation-framework,Json,Mongodb,Mongodb Query,Aggregation Framework,我想咨询一下如何使用MongoDB解决特定任务。我会尽我最大的努力解释整个画面,这样就不会出现XY问题。这将是一个有点长,所以我感谢所有谁得到的主题结束。我有一个包含报告的集合(我们称之为Cars)。所有报告都包含三个主要字段: 名字 颜色 时间戳 这些报告还包含其他字段,但它们与我的问题无关。我只想再解释一个字段-new\u start。如果new\u start位于报告中(意思是new\u start:1),则我忽略所有具有相同名称和颜色但为旧报告的报告,然后忽略包含new\u star
Cars
)。所有报告都包含三个主要字段:
- 名字
- 颜色
- 时间戳
new\u start
。如果new\u start
位于报告中(意思是new\u start:1
),则我忽略所有具有相同名称和颜色但为旧报告的报告,然后忽略包含new\u start
的报告(意思是时间戳小于所需报告)。我将试着用一个例子来解释。请考虑以下报道:
report1 - name: ABC, color: black, timestamp: 1581946973
report2 - name: ABC, color: black, timestamp: 1581946963
report3 - name: ABC, color: black, timestamp: 1581946953, new_start: 1
report4 - name: ABC, color: black, timestamp: 1581946943
report5 - name: ABC, color: black, timestamp: 1581946933, new_start: 1
report6 - name: ABC, color: black, timestamp: 1581946923
这些报告按时间戳(从最新到最旧)排序,并且都具有相同的名称和颜色。因此,我感兴趣的报告是:
report1 - name: ABC, color: black, timestamp: 1581946973
report2 - name: ABC, color: black, timestamp: 1581946963
report3 - name: ABC, color: black, timestamp: 1581946953, new_start: 1
请注意,如果没有带有new\u start
的报告,那么我将处理所有这些报告
我试图编写一个查询/代码,为我执行以下逻辑:对于包含相同名称和颜色的所有报告,获取所有报告。如果其中一个报告包含new\u start
,则它应返回从最新报告到该报告的报告
我尝试的内容(使用python和pymongo):
records = db.query(collection_name="cars", query={})
for record in records:
other_line_records = db.query(collection_name="cars", query={'name': record['name'], 'color': record['color'], '_id': {'$ne': record['_id']}})
# changes
merged\u cars
。合并逻辑在我得到所需的报告后我会自己做,但我很乐意在其他问题上得到帮助:
merged_cars
将反复使用相同的报告。我需要以某种方式跟踪合并的报告。我想创建一个包含所有合并ID的数组的字段merged\u id
。这样,我就知道是否有一个新的报告,我应该添加到合并。但是我应该如何有效地检查报告是否已经合并?另外,这是解决这个问题的有效方法吗?保存这些ID感觉有点奇怪new\u start
总而言之,由于我缺乏MongoDB聚合方面的经验,我似乎无法找到解决此问题的有效方法。我很高兴看到一些关于如何解决这个问题的建议(请提供一些例子,以便更容易理解)。正如您所看到的,我的主要问题是弄清楚这些查询应该是什么样子的。通过MongoDb聚合,我们可以实现这一点 解释
$group
使用相同的名称和颜色的所有记录,并将根文档存储到名为数据的临时字段中
数据
,我们找到所有带有new\u start
+和$reduce
的文档,我们返回最大的时间戳
$filter
我们将所有记录与max\u result
匹配,您真是太棒了!如果可以的话,我想问你几个问题。如果我将NumberLong(1581946933)
更改为1581946933
我得到1.581946972e+09
。你知道为什么吗?另外,关于合并部分-如何知道我是否在不使用$merge
的情况下处理尚未合并的报告?将来,它在操场上对我有用,但在pymongoresult\u docs=list(db[collection\u name].aggregate(mongo\u pipeline))
中返回false(我刚刚复制了聚合。有什么想法吗?再次感谢!@vesii我更新了我的答案。playmong中的NumberLong
可以避免1.581946972e+09
。您可以添加额外的字段(日期)要跟踪您的更改。您需要在引号中加上运算符、命令等…我明白了。不使用addFields
,是否可以实现?很遗憾,我必须使用mongo 3.2。很抱歉没有提及它before@vesii我们都不能使用$reduce
,$replaceRoot
…您至少需要更新MongoDB 3.4版本我目前使用的旧环境可以使用MongoDB 3.4或更高版本。3.2工具不可能吗?升级系统需要一些时间。您能建议其他方法吗?
db.Cars.aggregate([
{
$group: {
_id: {
name: "$name",
color: "$color"
},
data: {
$push: "$$ROOT"
}
}
},
{
$addFields: {
max_timestamp: {
$reduce: {
input: "$data",
initialValue: 0,
in: {
$cond: [
{
$and: [
{
$eq: [
"$$this.new_start",
1
]
},
{
$gt: [
"$$this.timestamp",
"$$value"
]
}
]
},
"$$this.timestamp",
"$$value"
]
}
}
}
}
},
{
$addFields: {
data: {
$filter: {
input: "$data",
cond: {
$lte: [
"$max_timestamp",
"$$this.timestamp"
]
}
}
}
}
},
{
$unwind: "$data"
},
{
$replaceRoot: {
newRoot: "$data"
}
}
])
{
$merge: {
into: "merged_cars",
on: "_id",
whenMatched: "replace",
whenNotMatched: "insert"
}
}
from pymongo import MongoClient
db = MongoClient('mongodb://localhost:27017').test
pipeline = [
{
'$group': {
'_id': {
'name': "$name",
'color': "$color"
},
'data': {
'$push': "$$ROOT"
}
}
},
{
'$addFields': {
'max_timestamp': {
'$reduce': {
'input': "$data",
'initialValue': 0,
'in': {
'$cond': [
{
'$and': [
{
'$eq': [
"$$this.new_start",
1
]
},
{
'$gt': [
"$$this.timestamp",
"$$value"
]
}
]
},
"$$this.timestamp",
"$$value"
]
}
}
}
}
},
{
'$addFields': {
'data': {
'$filter': {
'input': "$data",
'cond': {
'$lte': [
"$max_timestamp",
"$$this.timestamp"
]
}
}
}
}
},
{
'$unwind': "$data"
},
{
'$replaceRoot': {
'newRoot': "$data"
}
}
]
print(list(db.cars.aggregate(pipeline)))