Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.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
Json Efficient MongoDB查询以从一个集合中获取报告并插入到另一个集合中_Json_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Json Efficient MongoDB查询以从一个集合中获取报告并插入到另一个集合中

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

我想咨询一下如何使用MongoDB解决特定任务。我会尽我最大的努力解释整个画面,这样就不会出现XY问题。这将是一个有点长,所以我感谢所有谁得到的主题结束。我有一个包含报告的集合(我们称之为
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感觉有点奇怪

  • 目前,我只是迭代所有的报告,而没有实际使用MongoDB聚合的功能。我确信有一种更聪明、更高效的方法,这样我就不必一遍又一遍地重复所有合并的报告。但我似乎不明白怎么做

  • 我应该如何考虑
    new\u start


  • 总而言之,由于我缺乏MongoDB聚合方面的经验,我似乎无法找到解决此问题的有效方法。我很高兴看到一些关于如何解决这个问题的建议(请提供一些例子,以便更容易理解)。正如您所看到的,我的主要问题是弄清楚这些查询应该是什么样子的。

    通过MongoDb聚合,我们可以实现这一点

    解释
  • 我们
    $group
    使用相同的
    名称和
    颜色的所有记录,并将根文档存储到名为
    数据的临时字段中
  • 数据
    ,我们找到所有带有
    new\u start
    +和
    $reduce
    的文档,我们返回最大的
    时间戳

  • 使用
    $filter
    我们将所有记录与
    max\u result
    匹配,您真是太棒了!如果可以的话,我想问你几个问题。如果我将
    NumberLong(1581946933)
    更改为
    1581946933
    我得到
    1.581946972e+09
    。你知道为什么吗?另外,关于合并部分-如何知道我是否在不使用
    $merge
    的情况下处理尚未合并的报告?将来,它在操场上对我有用,但在pymongo
    result\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)))