Untitled

 avatar
unknown
plain_text
20 days ago
5.2 kB
1
Indexable
from pymongo import MongoClient
import mysql.connector
import pandas as pd
from datetime import datetime

# --- Kết nối MongoDB ---
mongo_client = MongoClient("mongodb://localhost:27017/")
mongo_db = mongo_client["nhan_khau_db"]
mongo_col = mongo_db["nhan_khau"]

# --- Kết nối MySQL ---
mysql_conn = mysql.connector.connect(
    host="localhost",
    user="root",
    password="11012004",
    database="nhakhau_db"
)
mysql_cursor = mysql_conn.cursor(dictionary=True)

# --- Truy vấn MongoDB phức tạp ---
def mongo_nguoi_nhieu_nghe(threshold=2):
    return mongo_col.aggregate([
        { "$project": { "cccd": 1, "so_nghe": { "$size": "$nghe_nghiep" } } },
        { "$match": { "so_nghe": { "$gt": threshold } } }
    ])

def mongo_nguoi_o_lau(years=10):
    cursor = mongo_col.find({}, {"cccd": 1, "dia_chi": 1})
    ket_qua = set()
    for doc in cursor:
        for dc in doc.get("dia_chi", []):
            try:
                tu = datetime.strptime(dc["tu_ngay"], "%Y-%m-%d")
                den = datetime.strptime(dc["den_ngay"], "%Y-%m-%d")
                if (den - tu).days / 365 >= years:
                    ket_qua.add(doc["cccd"])
                    break
            except:
                continue
    return ket_qua

def mongo_top_dia_chi(limit=5):
    return mongo_col.aggregate([
        { "$unwind": "$dia_chi" },
        { "$group": { "_id": "$dia_chi.ten_dia_chi", "so_nguoi": { "$sum": 1 } } },
        { "$sort": { "so_nguoi": -1 } },
        { "$limit": limit }
    ])

def mongo_top_nghe(limit=5):
    return mongo_col.aggregate([
        { "$unwind": "$nghe_nghiep" },
        { "$group": { "_id": "$nghe_nghiep.ten_nghe", "so_nguoi": { "$sum": 1 } } },
        { "$sort": { "so_nguoi": -1 } },
        { "$limit": limit }
    ])

# --- Truy vấn MySQL tương ứng ---
def mysql_query(sql):
    mysql_cursor.execute(sql)
    return mysql_cursor.fetchall()

# Người có nhiều nghề
def mysql_nguoi_nhieu_nghe(threshold=2):
    sql = f"""
    SELECT thanh_vien_cccd AS thanh_vien_id, COUNT(*) AS so_nghe
    FROM thanh_vien_nghe
    GROUP BY thanh_vien_cccd
    HAVING so_nghe > {threshold};
    """
    return {row["thanh_vien_id"] for row in mysql_query(sql)}


# Người từng sống ở nơi >10 năm
def mysql_nguoi_o_lau(years=10):
    sql = f"""
    SELECT t.thanh_vien_cccd AS thanh_vien_id
    FROM thanh_vien_dia_chi t
    WHERE DATEDIFF(STR_TO_DATE(t.den_ngay, '%Y-%m-%d'), STR_TO_DATE(t.tu_ngay, '%Y-%m-%d')) / 365 >= {years}
    GROUP BY t.thanh_vien_cccd;
    """
    return {row["thanh_vien_id"] for row in mysql_query(sql)}

# Top 5 địa chỉ có nhiều người cư trú
def mysql_top_dia_chi(limit=5):
    sql = f"""
    SELECT d.ten_dia_chi, COUNT(*) AS so_nguoi
    FROM dia_chi d
    JOIN thanh_vien_dia_chi t ON d.id_dia_chi = t.dia_chi_id
    GROUP BY d.ten_dia_chi
    ORDER BY so_nguoi DESC
    LIMIT {limit};
    """
    return mysql_query(sql)


# Top 5 nghề nghiệp
def mysql_top_nghe(limit=5):
    sql = f"""
    SELECT n.ten_nghe, COUNT(*) AS so_nguoi
    FROM nghe n
    JOIN thanh_vien_nghe t ON n.id_nghe = t.nghe_id
    GROUP BY n.ten_nghe
    ORDER BY so_nguoi DESC
    LIMIT {limit};
    """
    return mysql_query(sql)


# --- So sánh kết quả ---
def so_sanh_set(mongo_set, mysql_set, mo_ta):
    print(f"\n🔍 So sánh: {mo_ta}")
    print(f"MongoDB: {len(mongo_set)} | MySQL: {len(mysql_set)}")
    chen_lech = mongo_set.symmetric_difference(mysql_set)
    print(f"Chênh lệch: {len(chen_lech)} bản ghi {'(KHÔNG khớp)' if chen_lech else '(ĐÃ khớp)'}")

def in_top_ket_qua(mongo_cursor, mysql_rows, label="ten", value="so_nguoi"):
    # Chuyển MongoDB cursor thành DataFrame
    mongo_df = pd.DataFrame(mongo_cursor)
    mongo_df.columns = [label, f"{value}_mongo"]
    
    # MySQL kết quả → DataFrame
    mysql_df = pd.DataFrame(mysql_rows)
    mysql_df.columns = [label, f"{value}_mysql"]

    # Gộp theo nội dung
    merged = pd.merge(mongo_df, mysql_df, on=label, how="outer", indicator=True)
    
    print(f"\n📊 So sánh theo {label}")
    print(merged.to_string(index=False))

    # In chênh lệch
    khac = merged[merged["_merge"] != "both"]
    if not khac.empty:
        print("\n⚠️ Những dòng KHÔNG khớp:")
        print(khac.to_string(index=False))
    else:
        print("\n✅ TẤT CẢ địa chỉ khớp nội dung!")

# --- Chạy toàn bộ ---
if __name__ == "__main__":
    so_sanh_set(
        mongo_set={doc["cccd"] for doc in mongo_nguoi_nhieu_nghe()},
        mysql_set=mysql_nguoi_nhieu_nghe(),
        mo_ta="Người có hơn 2 nghề"
    )

    so_sanh_set(
        mongo_set=mongo_nguoi_o_lau(),
        mysql_set=mysql_nguoi_o_lau(),
        mo_ta="Người từng sống ở nơi >10 năm"
    )

    in_top_ket_qua(
        mongo_cursor=mongo_top_dia_chi(),
        mysql_rows=mysql_top_dia_chi(),
        label="ten_dia_chi"
    )

    in_top_ket_qua(
        mongo_cursor=mongo_top_nghe(),
        mysql_rows=mysql_top_nghe(),
        label="ten_nghe"
    )
Editor is loading...
Leave a Comment