2

コレクション全体のすべてのドキュメントの既存の属性でカスタム python 関数を呼び出し、その結果をその (同じ) ドキュメントに新しいキーと値のペアとして保存したいと考えています。それを行う方法があるかどうかを知ることができますか (各呼び出しは他の呼び出しから独立しているため) ?

気がついcursor.forEachたのですが、pythonを効率よく使うだけではできないのでしょうか?

簡単な例は、文字列を分割しtextて no を保存することです。新しい属性としての単語。

def split_count(text):
    # some complex preprocessing...

    return len(text.split())

# Need something like this...
db.collection.update_many({}, {'$set': {"split": split_count('$text') }}, upsert=True)

しかし、同じドキュメント内の別の属性の値に基づいてドキュメント内に新しい属性を設定することは、まだこの方法ではできないようです。この投稿は古いですが、問題はまだ未解決のようです。

4

2 に答える 2

3

PyMongo で parallel_scan使用して、コレクションで任意のカスタム python 関数を呼び出す方法を見つけました。

def process_text(cursor):
    for row in cursor.batch_size(200):
        # Any complex preprocessing here...
        split_text = row['text'].split()

        db.collection.update_one({'_id': row['_id']}, 
                                 {'$set': {'split_text': split_text, 
                                           'num_words': len(split_text) }},
                                 upsert=True)


def preprocess(num_threads=4):

    # Get up to max 'num_threads' cursors.
    cursors = db.collection.parallel_scan(num_threads)
    threads = [threading.Thread(target=process_text, args=(cursor,)) for cursor in cursors]

    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

これはそれほど速くはありませんがcursor.forEach(それほど遅くはありません)、任意の複雑な Python コードを実行し、Python 自体から結果を保存するのに役立ちます。

intsまた、属性の 1 つに の配列がある場合、実行すると、それらが望ましくないものにcursor.forEach変換されます。floatsだから私はこの方法を好みました。

しかし、これよりも良い方法があるかどうかを知ってうれしいです:)

于 2016-06-24T08:37:47.753 に答える