2017-11-24 16 views
0

publishedのキー日付が30日を超えると、いくつかのMongoDB文書を削除したいPythonスクリプトがあります。Pymongo特定の日付の後に文書を削除する

私のコードは、現在、次のとおりです。

def db_rotate(mongo_server, mongo_port): 
    try: 
     logging.info('Connecting to MongoDB') 
     client = MongoClient(mongo_server, mongo_port) 
     db = client['vuln_sets'] 
     logging.info('Connected to MongoDB') 
     today = datetime.now() 
     last_month = today - timedelta(days=30) 
     result = db.vulnerabilities.delete_many({'Published': last_month}) 
     logging.info('Deleted ' + str(result.deleted_count) + ' vulnerabilities') 
    except Exception as e: 
    logging.exception(e) 

このコードは、エラーなしで実行されますがPublishedキーで日付がUNIX形式で日付を持っているので、すべての文書を削除し、私はこれがあることを信じていません2017-10-30T11:36:20すなわち、一方、 last_month変数は異なる形式を使用します。

ドキュメントを挿入するコードは次のとおり

import json 
import logging 
import logging.handlers 
import os 
import pymongo 
from datetime import timedelta, datetime 
from pymongo import MongoClient 


def import_json(mongo_server,mongo_port, vuln_folder): 
    try: 
     logging.info('Connecting to MongoDB') 
     client = MongoClient(mongo_server, mongo_port) 
     db = client['vuln_sets'] 
     coll = db['vulnerabilities'] 
     logging.info('Connected to MongoDB') 
     basepath = os.path.dirname(__file__) 
     filepath = os.path.abspath(os.path.join(basepath, "..")) 
     archive_filepath = filepath + vuln_folder 
     filedir = os.chdir(archive_filepath) 
     file_count = 0 
     for item in os.listdir(filedir): 
      if item.endswith('.json'): 
       file_name = os.path.abspath(item) 
       with open(item, 'r') as currentfile: 
        vuln_counter = 0 
        duplicate_count = 0 
        logging.info('Currently processing ' + item) 
        file_count +=1 
        json_data = currentfile.read() 
        vuln_content = json.loads(json_data) 
        today = datetime.now() 
        last_month = today - timedelta(days=30) 
        for vuln in vuln_content: 
         try: 
          del vuln['_type'] 
          new_vuln = {key: vuln[key] for key in vuln if key != '_source'} 
          new_vuln.update(vuln['_source']) 
          if new_vuln['published'] >= str(last_month): 
           coll.insert(new_vuln, continue_on_error=True) 
           vuln_counter += 1 
          else: 
           pass 
         except pymongo.errors.DuplicateKeyError: 
          duplicate_count +=1 

       logging.info('Added ' + str(vuln_counter) + ' vulnerabilities for ' + item) 
       logging.info('Found ' + str(duplicate_count) + ' duplicate records!') 
       os.remove(file_name) 
     logging.info('Processed ' + str(file_count) + ' files') 
    except Exception as e: 
     logging.exception(e) 

挿入ドキュメントの例は次のとおり

{ 
    "_id" : "CESA-2017:3081", 
    "_index" : "bulletins", 
    "_score" : null, 
    "sort" : [ 
     103042 
    ], 
    "lastseen" : "2017-10-30T20:42:09", 
    "references" : [ 
     "https://access.redhat.com/errata/RHSA-2017:3081" 
    ], 
    "affectedPackage" : [ 

    ], 
    "description" : "", 
    "edition" : 1, 
    "reporter" : "", 
    "published" : "2017-10-30T11:36:20", 
    "title" : "", 
    "type" : "centos", 
    "enchantments" : { 

    }, 
    "bulletinFamily" : "unix", 
    "cvelist" : [ 
     "", 
    ], 
    "modified" : "2017-10-30T11:36:20", 
    "id" : "CESA-2017:3081", 
    "href" : "http://lists.centos.org/pipermail/centos-announce/2017-October/022611.html", 
    "cvss" : { 
     "score" : 6.8, 
     "vector" : "AV:NETWORK/AC:MEDIUM/Au:NONE/C:PARTIAL/I:PARTIAL/A:PARTIAL/" 
    } 
} 
+0

コレクションに書き込む機能を[MCVE](https://stackoverflow.com/help/mcve)に指定してください –

+0

ドキュメントの例を表示できますか? – Neodan

+0

MongoDBに書き込む文書の例とコードを追加しました – Luke

答えて

0

結果= db.vulnerabilities.delete_many({ '公開':last_month })

まず、フィールド名では大文字と小文字が区別されます。あなたの文書にはpublishedがありますが、質問にはの場合は大文字のPとなります。

ドキュメントに日付を文字列型として格納することに注意してください。可能であればPython datetime objectを使用してください。詳細および例については、PyMongo Datetimes and Timezonesも参照してください。すなわち

last_month = datetime.now() - timedelta(days=30) 

あなたが削除クエリに渡さlast_monthの値はdatetime.datetime(2017, 10, 28, 17, 36, 34, 358732)です。これをStringに変換する場合は、2017-10-28 17:36:34.358732となります。あなたが見ることができるように、両方の値はあなたが期待するものではありません。

datetime.datetime.strptime(string_date, "%Y-%m-%d %H:%M:%S.%f") 

は、上記のすべての言った、:

Date objectは、あなたが任意の日付の式を利用することができるものであるとして、値を格納するのもう一つの利点は、30日すなわち{published: {$gt: <30 days ago>}}

参照例にもdatetime.strptime to convert string to datetimeに合格しましたMongoDB内の特定のタイムスタンプを超えて文書を期限切れにしようとする場合は、MongoDB TTL IndexesTutorial: Expire Data from Collections by Setting TTLを参照してください。

関連する問題