0

モデルのクエリセットを反復処理し、一致するモデルを削除することを目的とした django コードのスニペットがあります。クエリセットが大きくなり、これらのアクションは実際には定期的なタスクに設定されているため、速度が問題になっています。

誰かがそれを最適化するのを手伝ってくれるなら、これがコードです!

# For the below code, "articles" are just django models

all_articles = [a reallly large list of articles]
newest_articles = [some large list of new articles]
unique_articles = []
for new_article in newest_articles:
    failed = False
    for old_article in all_articles:
        # is_similar is just a method which checks if two strings are
        # identical to a certain degree
        if is_similar(new_article.blurb, old_article.blurb, 0.9) 
            and is_similar(new_article.title, old_article.title, 0.92):
            failed = True
            break
    if not failed:
        unique_articles.append(new_article)
return unique_articles

ありがとうございます!

4

2 に答える 2

1

これにアプローチする1つの方法は、 Haystackを使用してコンテンツのSolrインデックスを維持し、Solrで各記事の一致を検索してから、それぞれの上位数個の一致をis_similar関数にフィードすることです。類似の記事を見つけるためにデータセット全体を検索する必要がない場合、パフォーマンスにかなり大きな違いが生じます。

于 2012-12-21T06:59:59.460 に答える
1

SQL レベルで "fuzzy DISTINCT" を実装する効率的な方法はないように思われるため、事前計算ルートを使用することをお勧めします。小さなコード スニペットからビジネス ロジックを推測しようとしているので、これは的外れかもしれませんが、新しい記事ごとに古い重複があるかどうかを知る必要があるように思えます (is_similar 関数で定義されているように)。その場合、実行可能なアプローチはis_duplicate、Article モデルにフィールドを追加し、記事が保存されるたびにバックグラウンド ジョブで再計算することです。例 ( Celeryを使用):

@task
def recompute_similarity(article_id):
    article = Article.objects.get(id=article_id)
    article.is_duplicate = False
    for other in Article.objects.exclude(id=article_id):
        if is_similar(article.title, other.title) or is_similar(article.blurb, other.blurb):
            article.is_duplicate = True
            break
     article.save()

def on_article_save(sender, instance, created, raw, **kwargs):
    if not raw:
        recompute_similarity.delay(instance.id)

signals.post_save.connect(on_article_save, sender=Article)

その後、元のルーチンはちょうど

Article.objects.filter(is_duplicate=False, ...recency condition)
于 2012-12-21T06:41:39.197 に答える