Импорт Mongodb в CSV - удаление дубликатов

1

Я импортирую данные из Mongo в CSV файл. Импорт состоит из "метки времени" и "текста" для каждого документа JSON.

Документы:

{ 
name: ..., 
size: ..., 
timestamp: ISODate("2013-01-09T21:04:12Z"), 
data: { text:..., place:...},
other: ...
}

Код:

with open(output, 'w') as fp:
   for r in db.hello.find(fields=['text', 'timestamp']):
       print >>fp, '"%s","%s"' % (r['text'], r['timestamp'].strftime('%H:%M:%S'))

Я хотел бы удалить дубликаты (некоторые Mongo docs имеют одинаковый текст), и я хотел бы сохранить первый экземпляр (относительно времени) неповрежденным. Можно ли удалить эти дубликаты при импорте?

Спасибо за вашу помощь!

  • 0
    Используйте структуру агрегирования и группу в обоих полях.
  • 0
    Я уверен, что ensureIndex({text}, {dropDups:true}) сохранит первый найденный нетронутым. Это может быть одним из способов, импортировать все, затем лишить дупс после
Теги:
duplicates
import

2 ответа

1
Лучший ответ

Вам просто нужно поддерживать карту (словарь) для поддержки пар (текст, метка времени). "Текст" - это ключ, поэтому дубликатов не будет. Я предполагаю, что порядок чтения не гарантированно возвращает самую старую временную метку. В этом случае вам нужно будет сделать 2 passes-- один раз для чтения, а затем один проход для записи.


textmap = {}

def  insert(text, ts):
    global textmap
    if  text in textmap: 
        textmap[text] = min(ts, textmap[text])
    else:
        textmap[text] = ts

for r in db.hello.find(fields=['text', 'timestamp']):
    insert(r['text'], r['timestamp'])

for text in textmap:
   print >>fp, text, textmap[text]  # with whatever format desired.

В конце вы также можете легко преобразовать словарь в список кортежей, если вы хотите отсортировать результаты, используя временную метку перед печатью, например.
(См. Раздел Сортировка словаря Python по значению)

3

Я бы использовал набор для хранения хэшей данных и проверял наличие дубликатов. Что-то вроде этого:

import md5

hashes = set()
with open(output, 'w') as fp:
   for r in db.hello.find(fields=['text', 'timestamp']):
       digest = md5.new(r['text']).digest()
       if digest in hashes:
            # It a duplicate!
            continue
       else:
            hashes.add(digest)
       print >>fp, '"%s","%s"' % (r['text'], r['timestamp'].strftime('%H:%M:%S'))

Стоит отметить, что вы можете использовать текстовое поле напрямую, но для больших текстовых полей сохранение только хеша гораздо более эффективно.

  • 0
    Там может быть столкновение в хеше. то есть 2 разных текста могут хэшировать одно и то же значение. В этом случае некоторые записи будут пропущены в выводе.
  • 0
    Но невероятно маловероятно, даже если MD5 не является устойчивым к столкновениям. Если ОП беспокоится об этом, он может сохранить текстовое поле в наборе, не хэшируя их, или использовать лучшую хэш-функцию, такую как SHA-3.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню