2017-11-24 1 views
0

Ich habe ein Python-Skript, das ich einige MongoDB-Dokumente löschen möchte, wenn das Schlüsseldatum published über 30 Tage ist.Pymongo löschen Dokumente nach einem bestimmten Datum

Mein Code zur Zeit ist:

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) 

Dieser Code läuft ohne Fehler entfernt jedoch nicht alle Dokumente, und ich glaube, dies zu sein, weil das Datum in der Published Taste, um das Datum in Unix-Format, dh 2017-10-30T11:36:20 hat während Die Variable last_month verwendet ein anderes Format.

Der Code, der die Dokumente eingefügt ist:

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) 

Ein Beispiel für die eingefügten Dokumente ist:

{ 
    "_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

Bitte liefern Sie [MCVE] (https://Stackoverflow.com/help/mcve) mit Funktion, die in Sammlung schreiben –

+0

Können Sie ein Dokument Beispiel zeigen? – Neodan

+0

Ich habe ein Dokumentbeispiel und den Code hinzugefügt, der in MongoDB schreibt – Luke

Antwort

0

result = db.vulnerabilities.delete_many ({ 'Veröffentlicht': last_month })

Zuerst sind die Feldnamen Groß-und Kleinschreibung. In Ihrem Dokument haben Sie published, aber in Ihrer Abfrage ist Kapital P für Published.

Beachten Sie auch, dass Sie die Daten in Ihrem Dokument als String-Typ speichern, verwenden Sie so oft wie möglich Python datetime object. Siehe auch PyMongo Datetimes and Timezones für weitere Informationen und Beispiele. das heißt

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

Der Wert last_month, wenn Sie in die Lösch-Abfrage übergeben wird datetime.datetime(2017, 10, 28, 17, 36, 34, 358732). Wenn Sie dies in String konvertieren würden, wäre es 2017-10-28 17:36:34.358732. Wie Sie sehen können, sind beide Werte nicht das, was Sie erwarten.

Ein weiterer Vorteil der Speicherung des Wertes als Date object ist, dass Sie einen Ausdruck für alle Daten 30 Tage dh {published: {$gt: <30 days ago>}}

Siehe datetime.strptime to convert string to datetime zum Beispiel auch bestanden nutzen können:

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

sagte Nachdem das vor allem, Wenn Sie beabsichtigen, ein Dokument innerhalb von MongoDB nach einem bestimmten Zeitstempel zu verfallen, finden Sie weitere Informationen unter MongoDB TTL Indexes und Tutorial: Expire Data from Collections by Setting TTL.

Verwandte Themen