之前设置唯一索引的时候, 没有设置 unique 选项, 导致数据库中出现了重复数据。 不想 drop 掉重新拉, 就尝试了下数据的清理, 方便之后也可能会用到。
链接: https://blog.csdn.net/cloume/article/details/74931998
参考了这个, 最终决定用 脚本加 命令行 手动实现。
import pymongo
import logging
import time
import pandas as pd
from collections import defaultdict
from all_codes import all
t1 = time.time()
# 默认是是列表的字典
error_codes = defaultdict(list)
error_date = set([])
MongoUri = "mongodb://127.0.0.1:27017"
db = pymongo.MongoClient(MongoUri)
codes = all
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG,
filename='clean.log',
datefmt='%Y/%m/%d %H:%M:%S',
format='%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(module)s - %(message)s')
def convert(code):
if code[0] == "0" or code[0] == "3":
return "SZ" + code
elif code[0] == "6":
return "SH" + code
else:
pass
for c in codes:
code = convert(c)
logger.info(code)
# 找出全部唯一的 date_int
dis_date_ints = db.stock.calendar.find({"code": code}).distinct("date_int")
cursor = db.stock.calendar.find({"code": code}, {"date_int": 1, "_id": 0})
all_date_ints = [r.get("date_int") for r in cursor]
# 无需进行清理的部分
if sorted(dis_date_ints) == sorted(all_date_ints):
logger.info("ok")
else:
logger.info("no")
df = pd.DataFrame({"date": all_date_ints})
# 使用 df 中的方法清除重复数据
dup = df[df.duplicated()]
to_delete = dup["date"].tolist()
logger.info(to_delete)
error_codes[code].extend(to_delete)
error_date = error_date | set(to_delete)
t2 = time.time()
logger.info(t2 - t1)
logger.info(error_codes)
logger.info(error_date)
主要感觉这样比较可控, 就没有直接在程序中删除 。
比如以上,就说明是 SH600136 这只股票在 20180708 的数据有重复。
找到非 SH000001 的部分进行清理:
db.calendar.find({"date_int": 20190527, "code": {$ne: "SH000001"}}).count()
删除多个重复的数据中的一个, (在查出有两个数据的时候适用)
db.calendar.remove({"code": "SH600136", "date_int":20180708}, {"justOne": true})
在清理过后尝试设置惟一的联合索引值:
db.justtest.ensureIndex({"code": 1, "date_int": 1}, {unique: true})
在已经有数据的集合中尝试建立唯一索引,还是有重复值的话就会报错:
"errmsg" : "{ rs1/Lianghua_HW_GZ_124:27101,Lianghua_HW_GZ_152:27101,Lianghua_HW_GZ_163:27101:
\"Index with name: code_1_date_int_1 already exists with different options\" }"
更新:20190601
我们需要删除之前的索引才可以插入新的 不删除原来的同名索引的时候, 会报错:
"errmsg" : "{ rs1/Lianghua_HW_GZ_124:27101,Lianghua_HW_GZ_152:27101,Lianghua_HW_GZ_163:27101: " \
"\"Index with name: code_1_date_int_1 already exists with different options\" }"
db.calendar.dropIndex("code_1_date_int_1")
删除索引的命令:
db.calendar.dropIndex("code_1_date_int_1")
更新于: 2019.6.19
在mongo shell 命令行中查看数据库的索引: getIndexes()
在 date和 index之间建立唯一索引:
db.generate_indexcomponentsweight.ensureIndex({“date”: 1, “index”: 1}, {unique: true})
再次查看: