Я импортирую данные из 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 имеют одинаковый текст), и я хотел бы сохранить первый экземпляр (относительно времени) неповрежденным. Можно ли удалить эти дубликаты при импорте?
Спасибо за вашу помощь!
Вам просто нужно поддерживать карту (словарь) для поддержки пар (текст, метка времени). "Текст" - это ключ, поэтому дубликатов не будет. Я предполагаю, что порядок чтения не гарантированно возвращает самую старую временную метку. В этом случае вам нужно будет сделать 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 по значению)
Я бы использовал набор для хранения хэшей данных и проверял наличие дубликатов. Что-то вроде этого:
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'))
Стоит отметить, что вы можете использовать текстовое поле напрямую, но для больших текстовых полей сохранение только хеша гораздо более эффективно.
ensureIndex({text}, {dropDups:true})
сохранит первый найденный нетронутым. Это может быть одним из способов, импортировать все, затем лишить дупс после