Twitter的Tweet ID是否全平台唯一?存储报错问题求证
首先可以明确地说:Twitter的Tweet ID确实是全平台唯一的。它基于类似Snowflake的算法生成,每个ID包含时间戳、生成该ID的Twitter内部节点标识,以及同一节点下的序列号——这三个维度的组合确保了无论哪个用户的推文,ID在整个Twitter平台都不会重复。
那你遇到的E11000 duplicate key error肯定不是Tweet ID本身的问题,大概率出在你的代码逻辑或者数据获取环节,我帮你梳理几个可能的原因和排查方向:
1. 代码中的数据处理错误
看你贴的代码,第一个循环里有个明显的问题:
processed_tweets = [] for tweet in tweets: processed_tweets = process_tweet(tweet) # 这里每次循环都会覆盖列表,而不是添加元素
你把processed_tweets初始化成了列表,但每次循环都直接把它赋值为process_tweet的返回值(应该是单个处理后的字典),最后processed_tweets只会保留最后一条处理后的推文。如果后续循环遍历这个变量(如果它是字典的话,会遍历键),就可能出现重复插入同一条数据的情况,自然会触发重复键错误。
修正这个问题很简单,把赋值改成追加:
processed_tweets.append(process_tweet(tweet))
2. 重复获取了同一条推文
有可能你的上游数据拉取逻辑有问题——比如API请求重试、分页参数错误,导致同一条推文被多次拉取到tweets列表里。这种情况下,即使Tweet ID本身唯一,重复插入自然会报错。
你可以在处理前先打印或者校验tweets里的ID,看看是否有重复项,或者在插入前做个去重处理:
# 用集合去重,基于Tweet ID seen_ids = set() unique_tweets = [] for tweet in tweets: tweet_id = tweet.id_str # 或者根据你的数据结构获取ID if tweet_id not in seen_ids: seen_ids.add(tweet_id) unique_tweets.append(tweet) # 再处理unique_tweets
3. process_tweet函数的逻辑错误
检查一下process_tweet函数,有没有可能在转换tweepy对象为字典时,错误地把不同推文的_id设置成了同一个值?比如函数内部的变量没有正确重置,或者取错了属性(比如不小心用了用户ID而不是推文ID)。
你可以在处理后打印processed_tweets里的每个_id,确认它们是否和原始推文的ID对应。
最后给你修正后的完整代码参考:
def write_tweets_to_db(tweets): processed_tweets = [] # 先做去重处理 seen_ids = set() for tweet in tweets: tweet_id = tweet.id_str # 根据你的tweepy对象实际属性调整 if tweet_id not in seen_ids: seen_ids.add(tweet_id) processed_tweets.append(process_tweet(tweet)) for tweet in processed_tweets: try: collection.insert_one(tweet) except Exception as e: # 打印具体的ID方便排查 print(f'Error while writing tweet {tweet["_id"]} to DB | Error: {e}')
内容的提问来源于stack exchange,提问作者idar

