find
ステートメントが空でないクエリを返すかどうかを確認する必要があります。
私がやっていたことは次のとおりでした:
_query = collection.find({"string": field})
if not query: #do something
_
次に、if
がカーソルを返すため、クエリが空かどうかに関係なく、find
ステートメントが実行されないことに気付きました。
したがって、私は documentation をチェックし、私を助けることができる2つの方法を見つけました:
count(with_limit_and_skip=False)
which(説明から):
このクエリの結果セットにあるドキュメントの数を返します。
チェックするのに良い方法のように思えますが、これは、カーソル内のすべての結果をカウントして、ゼロかどうかを知る必要があることを意味しますよね?少し高い?
retrieved
which(説明から):
これまでに取得されたドキュメントの数。
空のクエリセットでテストし、ゼロを返しますが、それが何をするのかは明確ではなく、自分に適しているかどうかはわかりません。
それでは、find()
クエリが空のセットを返すかどうかを確認する最良の方法(ベストプラクティス)はどれですか。上記の方法の1つがこの目的に適していますか?そして、パフォーマンスはどうですか?他の方法がありますか?
明確にするために:クエリが空かどうかを知る必要があり、パフォーマンスとPythonicに関して、カーソルを使用して最適な方法を見つけたいと思います。
[〜#〜] edit [〜#〜]:これは2014年に当てはまりましたが、pymongoおよびMongoDBの最新バージョンこの動作を変更しました。バイヤーは注意してください:
.count()
は、クエリで返される結果の数を見つける正しい方法です。 count()
メソッドはカーソルの反復子を使い果たしません。そのため、結果セットの項目を反復処理する前に.count()
チェックを安全に行うことができます。
Countメソッドのパフォーマンスは、MongoDB 2.4で大幅に改善されました。 count
を遅くする可能性があるのは、クエリにインデックスが設定されているかどうかだけです。クエリにインデックスがあるかどうかを確認するには、次のようなことができます
query = collection.find({"string": field})
print query.explain()
結果にBasicCursor
が表示される場合、このクエリのstring
フィールドにインデックスが必要です。
[〜#〜] edit [〜#〜]:@alvapanが指摘したように、 pymongoは非推奨 pymongo 3.7のメソッド+そして今ではcount_documents
別のクエリで。
item_count = collection.count_documents({"string": field})
クエリで返されたアイテムの数をカウントする正しい方法は、.retreived
クエリを反復処理した後、または最初の場所のenumerate
クエリにカウンターします。
# Using .retrieved
query = collection.find({"string": field})
for item in query:
print(item)
print('Located {0:,} item(s)'.format(query.retrieved))
または、別の方法:
# Using the built-in enumerate
query = collection.find({"string": field})
for index, item in enumerate(query):
print(item)
print('Located {0:,} item(s)'.format(index+1))
find
の代わりにfind_one
を使用するだけではどうですか?その後、結果が得られたか、None
かを確認するだけです。また、「string」にインデックスが付けられている場合は、fields = {"string":1, "_id" :0}
を渡すことができるため、インデックスのみのクエリにできます。これはさらに高速です。
別の解決策は、カーソルをリストに変換することです。カーソルにデータがない場合は空のリスト、リストにはすべてのデータが含まれます。
doc_list = collection.find({}); #find all data
have_list = True if len(list(doc_list)) else False;
私のテストから、最も簡単な方法は
if query.first():
# do something
In [51]: %timeit query = MyMongoDoc.objects(); query.first()
100 loops, best of 3: 2.12 ms per loop
In [52]: %timeit query = MyMongoDoc.objects(); query.count()
100 loops, best of 3: 4.28 ms per loop
(MongoDB 2.6.7、2015-03-26を使用)