جلوگیری از ذخیره لینک های تکراری در دیتابیس mongodb

پرسیده شده
فعالیت 1001 روز پیش
دیده شده 402 بار
0

سلام

در جلسه ی مربوط به ذخیره لینک های اگهی در دیتابیس استاد متد زیر رو برای ذخیره کردن لینک ها نوشتن

    def store(self, data, collection_name):
        collection = getattr(self.mongo.database, collection_name)
        if isinstance(data, list) and len(data) > 1:
            collection.insert_many(data)
        else:
            collection.insert_one(data)

حالا سوال من اینه 

وقتی ما هر بار برنامه رو اجرا میکنیم این متد همه ی لینک ها رو داخل دیتابیس ذخیره میکنه

حتی لینک هایی که قبلا هم ذخیره کرده

 

چطوری میشه جلوی این کار رو گرفت؟

 

البته من خودم یه یکم این متد رو تغییر دادم و تونستم جلوی ذخیره لینک های تکراری رو بگیرم

اما نمیدونم کاری که کردم بهینه هست یا نه؟

    def store(self, data, collection_name):
        collection = getattr(self.mongo.database, collection_name)
        collection.create_index('url', unique=True)
        if isinstance(data, list) and len(data) >= 1:
            for record in data:
                try:
                    collection.insert_one(record)
                except pymongo.errors.DuplicateKeyError:
                    print(f'This key {record["url"]} exits in database.')
                    continue

ممنون میشم راهنمایی ام کنید.

 

data = [
	{'_id': ObjectId(), 'url': 'url_1', 'flag': False},
	{'_id': ObjectId(), 'url': 'url_2', 'flag': False},
	{'_id': ObjectId(), 'url': 'url_3', 'flag': False},
	...
]
فایل پیوست

Mohsen Azizi
Mohsen Azizi

14 مرداد 00

0
حذف شده

سلااااااااااااااااام محسن جان

یه مفهومی تو زمینه دیتابیس داریم که بهش میگن upsert، از ترکیب کلمه insert و update به وجود اومده. توی PostgreSQL میشه ۲ تا کار زیر رو انجام داد:

- رکورد رو ایجاد کن و اگر وجود داشت هیچ کاری نکن.

- رکورد رو ایجاد کن و اگر وجود داشت آپدیتش کن.

تو mongoDB هم مفهوم upsert رو داریم. البته فقط حالت دوم رو، یعنی داکیومنت رو ایجاد کن و اگر وجود داشت آپدیتش کن. برای انجام حالت اول میتونیم از ترکیب دو دستور findOne و insertOne استفاده کنیم.

برای upsert کردن میتونیم از متدهای زیر:

- updateOne

- updateMany

- findOneAndUpdate

همراه با آرکومان upsert=Ture استفاده کنیم.

لینک هایی که گذاشتم رو بخون. به توضیحات آرگومان upsert هم حتما دقت کن:

Optional. When true, updateOne() either:

Creates a new document if no documents match the filter. For more details see upsert behavior.

Updates a single document that matches the filter.

To avoid multiple upserts, ensure that the filter field(s) are uniquely indexed.

Defaults to false, which does not insert a new document when no match is found.


توی کدی که فرستادی یه مساله به چشمم خورد. خط 4 بجای =< از < باید استفاده کنی. و نیاز هست برای if قسمت else هم بذاری که اگر یه داکیومنت بود توی else ایجادش کنی.

 

تو این کد بهتره از کدوم متد استفاده کنیم؟

کدش رو بنویس و بفرس تا در موردش صحبت کنیم.

 

باز اگر سوالی داشتی در خدمتم :)

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

14 مرداد 00

0
حذف شده

سلامی دوباره

ممنون از توضیحات خوبتون

با توجه به توضیحات من کدم رو اصلاح کردم

    def store(self, data, collection_name):
        collection = getattr(self.mongo.database, collection_name)
        if isinstance(data, list) and len(data) > 1:
            for record in data:
                if not collection.find_one({'url': record['url']}):
                    collection.insert_one(record)

                # collection.update_one(
                #     filter={'url': record['url']},
                #     update={'$set': {'flag': False}},
                #     upsert=True
                # )
        else:
            if not collection.find_one({'url': data['url']}):
                collection.insert_one(data)

            # collection.update_one(
            #     filter={'url': data['url']},
            #     update={'$set': {'flag': False}},
            #     upsert=True
            # )

من از هر دو روش گفته شده استفاده کردم

 

مشکلی که با روش دوم دارم اینه که این کد هر زمانی اجرا بشه میره یه رکورد رو داخل دیتابیس آپدیت میکنه

در نتیجه مقدار flag رو همیشه false یا true میکنه( update={'$set': {'flag': False}} ) که نباید این طوری باشه

 

اما راه حل اول کاملا درسته اجرا میشه

 

نمیدونم راهی برای حل این موضوع هست یا نه؟

فایل پیوست

Mohsen Azizi

توسط

Mohsen Azizi

14 مرداد 00

جلسه کراول آگهی‌های خانه - ذخیره لینک‌ها در MongoDB