MongoDB 数据库数据导入/出教程

前篇提到了服务端 241220 的启动关联到了 mongodb,也至于我没用过这玩意,搞得我一头雾水,经过了半个月的琢磨,也算是掌握了一些基本操作,接下来我将讲解一下几点,从而让我们在使用 MongoDB 时更加得心应手。

  • 导入

  1. 打开 MongoDB 的 GUI 面板,创建一个我们自己的数据库 (面板上找到并点击 localhost:27017 右面的+号),名字为 boombeach,集合名字为 pp,然后点击 create database 即完成创建
  2. 看似空空如也,我们现在开始导入玩家数据 (海岛服务端中的 pp 文件夹内的 json 数据文件),先选中集合 pp 文件夹,然后点击 add data,然后点击 import json or csv file,然后导入 0.json
  3. 打开海岛奇兵服务端 (确保不闪退,可以正常运行,如果闪退那就是 0.json 你没搞好,我在上一篇搭建 241220 服务端中提到过,你需要删除一些段落并将 {} 替换为 []),然后打开 GUI 面板,删除所有玩家数据,点垃圾桶图标即可
  4. 在海岛服务端面板中输入 (不能有玩家在线)
    /mongoimportpp

    等待一会后便导入完成,你会在 mongodb 面板中的 pp 文件夹内看到所有玩家数据了

  • 导出

  1. 安装 python
  2. 打开 cmd 终端命令窗口,输入以下代码,目的是下载一个数据库
 pip install pymongo

如果出现以下内容,那么则代表下载完毕

  • 之后创建一个 py 文件,直接创建一个 txt 文本文件改后缀即可

此 py 文件内容如下:

import sys
from pymongo import MongoClient
import json
import os

# 核心配置 (只留必要项)
SAVE_DIR = "D:/MongoDB 数据库玩家 json 文件夹"
COLLECTIONS = ["pp", "level"]  # 要导出的集合
# 优先用数据里的唯一字段当文件名 (按实际字段调整,没有则用索引)
FILE_NAME_FIELD = ["player_id", "id", "user_id"]  # 顺序:先找 player_id,再找 id...

def get_filename(data, index):
    """获取文件名:优先用数据里的唯一字段,没有则用索引"""
    for field in FILE_NAME_FIELD:
        if field in data:
            return f"{data[field]}.json"  # 用唯一字段当文件名 (如 12345.json)
    return f"{index}.json"  # 无唯一字段时用索引命名

def main():
    # 询问确认
    print(f"导出路径:{SAVE_DIR}(不存在会自动创建)")
    if input("是否继续?(y=是,其他=否):").strip().lower() != "y":
        print("程序退出")
        return

    # 连接数据库
    try:
        client = MongoClient('mongodb://localhost:27017/')
        db = client.boombeach
        print("MongoDB 连接成功")
    except Exception as e:
        print(f"数据库连接失败:{e}")
        return

    # 创建文件夹
    try:
        for coll in COLLECTIONS:
            coll_dir = os.path.join(SAVE_DIR, coll)
            if not os.path.exists(coll_dir):
                os.makedirs(coll_dir)
        print("文件夹创建完成")
    except Exception as e:
        print(f"文件夹创建失败:{e}")
        return

    # 导出数据 (不修改原始数据,只删_id)
    for coll in COLLECTIONS:
        print(f"\n 开始导出 {coll} 集合...")
        collection = db[coll]
        total = collection.count_documents({})
        print(f"共 {total} 条数据")

        if total == 0:
            print(f"{coll} 集合无数据,跳过")
            continue

        success = 0
        for idx, data in enumerate(collection.find()):
            try:
                data.pop('_id', None)  # 只移除数据库自动生成的字段,不碰原始数据
                filename = get_filename(data, idx)
                file_path = os.path.join(SAVE_DIR, coll, filename)
                # 保存原始数据 (不修改任何字段和值)
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(data, f, indent=2, ensure_ascii=False, default=str)
                success += 1
            except Exception as e:
                print(f"第 {idx} 条数据失败:{e}")

        print(f"{coll} 导出完成:成功 {success} 条,失败 {total-success} 条")

    print(f"\n 所有导出完成,文件路径:{SAVE_DIR}")
    input("按回车关闭...")

if __name__ == "__main__":
    main()

我这里将导出路径设置为了 MongoDB 数据库玩家 json 文件夹的文件名,你只需要去 D 盘根目录创建一个 「MongoDB 数据库玩家 json 文件夹」 的文件名即可,执行 py 后这个文件夹内自然会出现带有序号的 json 玩家数据,这些数据都应该存放在服务器的 pp 文件夹中,每一个序号代表一个玩家。

 

第二个是单独导出 (选项性,既可以单独也可以一键导出):

import sys
from pymongo import MongoClient
import json
import os

# 核心配置
SAVE_DIR = "MongoDB 数据库玩家 json 文件夹"
PP_COLLECTION = "pp"          # pp 集合名称
LEVEL_COLLECTION = "level"    # level 集合名称
PP_MATCH_FIELD = "PlayerID"   # pp 集合查询字段 (PlayerID)
LEVEL_MATCH_FIELDS = ["player_id", "id", "user_id", "home_id"]  # level 集合与 PlayerID 匹配的字段 (顺序匹配)

def get_filename(data, coll_name, index=0):
    """生成文件名:优先用匹配字段,无则用索引"""
    if coll_name == PP_COLLECTION and PP_MATCH_FIELD in data:
        return f"{data[PP_MATCH_FIELD]}.json"
    elif coll_name == LEVEL_COLLECTION:
        for field in LEVEL_MATCH_FIELDS:
            if field in data:
                return f"{data[field]}.json"
    return f"数据_{index}.json"

def export_specific_player(player_id):
    """单独导出指定 PlayerID 的 pp 和 level 数据 (无则忽略)"""
    print(f"\n🔍 正在查询 PlayerID = {player_id} 的关联数据...")

    # 连接数据库
    try:
        client = MongoClient('mongodb://localhost:27017/')
        db = client.boombeach
        print("✅ MongoDB 连接成功!")
    except Exception as e:
        print(f"❌ 数据库连接失败:{e}")
        return

    # 创建存储文件夹 (确保目录存在)
    pp_dir = os.path.join(SAVE_DIR, PP_COLLECTION)
    level_dir = os.path.join(SAVE_DIR, LEVEL_COLLECTION)
    for dir_path in [pp_dir, level_dir]:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

    # 1. 导出 pp 集合数据
    print("\n" + "-" * 50)
    print(f"📤 导出 {PP_COLLECTION} 集合数据...")
    pp_coll = db[PP_COLLECTION]
    pp_query = {PP_MATCH_FIELD: player_id}
    pp_data_list = list(pp_coll.find(pp_query))

    if pp_data_list:
        print(f"✅ 找到 {len(pp_data_list)} 条 pp 数据")
        for idx, data in enumerate(pp_data_list):
            data.pop('_id', None)  # 移除数据库自动字段
            filename = get_filename(data, PP_COLLECTION, idx)
            file_path = os.path.join(pp_dir, filename)
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2, ensure_ascii=False, default=str)
            print(f"   ✅ 已保存:{file_path}")
    else:
        print(f"ℹ️  未找到 {PP_COLLECTION} 集合中 PlayerID = {player_id} 的数据 (已忽略)")

    # 2. 导出 level 集合关联数据 (匹配任意字段,无则忽略)
    print("\n" + "-" * 50)
    print(f"📤 导出 {LEVEL_COLLECTION} 集合关联数据...")
    level_coll = db[LEVEL_COLLECTION]
    level_data_list = []
    matched_field = None

    # 按顺序匹配 level 集合的字段
    for field in LEVEL_MATCH_FIELDS:
        level_query = {field: player_id}
        temp_data = list(level_coll.find(level_query))
        if temp_data:
            level_data_list = temp_data
            matched_field = field
            break

    if level_data_list:
        print(f"✅ 找到 {len(level_data_list)} 条 level 数据 (匹配字段:{matched_field})")
        for idx, data in enumerate(level_data_list):
            data.pop('_id', None)  # 移除数据库自动字段
            filename = get_filename(data, LEVEL_COLLECTION, idx)
            file_path = os.path.join(level_dir, filename)
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2, ensure_ascii=False, default=str)
            print(f"   ✅ 已保存:{file_path}")
    else:
        print(f"ℹ️  未找到 {LEVEL_COLLECTION} 集合中与 PlayerID = {player_id} 匹配的数据 (已忽略)")

    print("\n" + "=" * 50)
    print("🎉 指定玩家数据导出完成!")
    print(f"📁 文件存储根路径:{os.path.abspath(SAVE_DIR)}")
    print("=" * 50)

def batch_export_all():
    """全部导出 pp 和 level 集合所有数据"""
    print(f"\n📂 导出根路径:{os.path.abspath(SAVE_DIR)}")
    print(f"📊 待导出集合:{PP_COLLECTION} 、 {LEVEL_COLLECTION}")
    print("=" * 50)
    if input("是否开始全部导出?(y=是,其他=否):").strip().lower() != "y":
        print("🚫 程序退出")
        return

    # 连接数据库
    try:
        client = MongoClient('mongodb://localhost:27017/')
        db = client.boombeach
        print("✅ MongoDB 连接成功!")
    except Exception as e:
        print(f"❌ 数据库连接失败:{e}")
        return

    # 创建文件夹
    for coll in [PP_COLLECTION, LEVEL_COLLECTION]:
        coll_dir = os.path.join(SAVE_DIR, coll)
        if not os.path.exists(coll_dir):
            os.makedirs(coll_dir)
            print(f"✅ 已创建文件夹:{coll_dir}")

    # 批量导出每个集合
    for coll_name in [PP_COLLECTION, LEVEL_COLLECTION]:
        print("\n" + "=" * 60)
        print(f"📤 开始导出 [{coll_name}] 集合所有数据...")
        print("=" * 60)
        collection = db[coll_name]
        total = collection.count_documents({})
        print(f"ℹ️  [{coll_name}] 集合共查询到 {total} 条数据")

        if total == 0:
            print(f"ℹ️  [{coll_name}] 集合无数据,跳过导出")
            continue

        success = 0
        used_filenames = set()
        for idx, data in enumerate(collection.find()):
            try:
                data.pop('_id', None)
                filename = get_filename(data, coll_name, idx)
                # 处理文件名冲突
                while filename in used_filenames:
                    filename = f"{filename[:-5]}_重复 {len(used_filenames)}.json"
                used_filenames.add(filename)
                # 保存文件
                file_path = os.path.join(SAVE_DIR, coll_name, filename)
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(data, f, indent=2, ensure_ascii=False, default=str)
                success += 1
                if idx % 10 == 0:  # 每 10 条输出一次进度 (避免刷屏)
                    print(f"ℹ️  已导出 {success}/{total} 条数据")
            except Exception as e:
                print(f"❌ 第 {idx+1} 条数据导出失败:{str(e)[:50]}...")

        print(f"\n📊 [{coll_name}] 集合导出统计:")
        print(f"   总数据量:{total} 条")
        print(f"   成功导出:{success} 条")
        print("-" * 60)

    print("\n" + "=" * 60)
    print("🎉 全部数据导出完成!")
    print(f"📁 最终文件路径:{os.path.abspath(SAVE_DIR)}")
    print("=" * 60)

def main():
    # 程序入口:简洁选项
    print("=" * 60)
    print("          MongoDB 数据导出工具")
    print("=" * 60)
    print("📌 导出选项:")
    print("   1 - 单独导出指定玩家的数据")
    print("   2 - 全部导出 (pp + level 所有数据)")
    print("=" * 60)

    # 选择功能 (容错处理)
    while True:
        choice = input("请输入选择 (1 或 2):").strip()
        if choice in ["1", "2"]:
            break
        print("❌ 输入无效!请仅输入 1 或 2")

    if choice == "1":
        # 单独导出:询问 PlayerID
        while True:
            player_id_input = input("\n 请输出该玩家的 PlayerID:").strip()
            if player_id_input:
                # 兼容数字/字符串类型的 PlayerID
                try:
                    player_id = int(player_id_input)
                except ValueError:
                    player_id = player_id_input
                break
            print("❌ PlayerID 不能为空,请重新输入!")
        export_specific_player(player_id)
    else:
        batch_export_all()

    # 防止程序闪退
    input("\n 按回车关闭程序...")

if __name__ == "__main__":
    main()

搜索

以 {"PlayerID": 12} 为例子

playerid 就是大类,而 12 是这一类其中一个 json 数据的一个数值,其他搜索方法也是如此

如果我们需要查找玩家名字,通过名字来找到对方 ID 并实时操作

{"PlayerName": "哈哈"}

{"playername": "BOSS"}

标题:MongoDB 数据库数据导入/出教程
链接:https://blog.30hb.cn/207/
作者:Baie--0v0
暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇