2017-08-04 15 views
2

データベースに存在するn個のオブジェクトと完全に一致するMongo DBにヒットできるPyMongoを使用してPythonスクリプトを作成しようとしています。私は、リスト内の10かそこらのアイテムを持っているとき$orを使用して複数のドキュメントフィールドでのMongoDBの完全一致

[{'email': '[email protected]', 'zip': '11111'}, {'email': '[email protected]', 'zip': '11112'}, ...] 

は大丈夫作品:オブジェクトのリストは、次のようになります

db.entries.find({'$or': [<list-of-objects]}) 

:現在、私は、このセットアップを持っています。私は今100でテストしています、そしてそれは返すのに非常に長い時間がかかります。私は複数の$inフィルタを使用することを検討しましたが、それが最良のオプションかどうかはわかりません。

これを処理するより良い方法があると確信していますが、私はかなり新しいMongoです。

EDIT:

db.entries.createIndex({"email": 1, "zip": 1}) 

{ 
    "executionStats": { 
     "executionTimeMillis": 228734, 
     "nReturned": 2, 
     "totalKeysExamined": 0, 
     "allPlansExecution": [], 
     "executionSuccess": true, 
     "executionStages": { 
      "needYield": 0, 
      "saveState": 43556, 
      "restoreState": 43556, 
      "isEOF": 1, 
      "inputStage": { 
       "needYield": 0, 
       "saveState": 43556, 
       "restoreState": 43556, 
       "isEOF": 1, 
       "inputStage": { 
        "needYield": 0, 
        "direction": "forward", 
        "saveState": 43556, 
        "restoreState": 43556, 
        "isEOF": 1, 
        "docsExamined": 5453000, 
        "nReturned": 2, 
        "needTime": 5452999, 
        "filter": { 
         "$or": [{ 
          "$and": [{ 
           "email": { 
            "$eq": "[email protected]" 
           } 
          }, { 
           "zipcode": { 
            "$eq": "11111" 
           } 
          }] 
         }, { 
          "$and": [{ 
           "email": { 
            "$eq": "[email protected]" 
           } 
          }, { 
           "zipcode": { 
            "$eq": "11112" 
           } 
          }] 
         }] 
        }, 
        "executionTimeMillisEstimate": 208083, 
        "invalidates": 0, 
        "works": 5453002, 
        "advanced": 2, 
        "stage": "COLLSCAN" 
       }, 
       "nReturned": 2, 
       "needTime": 5452999, 
       "executionTimeMillisEstimate": 211503, 
       "transformBy": { 
        "_id": false 
       }, 
       "invalidates": 0, 
       "works": 5453002, 
       "advanced": 2, 
       "stage": "PROJECTION" 
      }, 
      "nReturned": 2, 
      "needTime": 5452999, 
      "executionTimeMillisEstimate": 213671, 
      "invalidates": 0, 
      "works": 5453002, 
      "advanced": 2, 
      "stage": "SUBPLAN" 
     }, 
     "totalDocsExamined": 5453000 
    }, 
    "queryPlanner": { 
     "parsedQuery": { 
      "$or": [{ 
       "$and": [{ 
        "email": { 
         "$eq": "[email protected]" 
        } 
       }, { 
        "zipcode": { 
         "$eq": "11111" 
        } 
       }] 
      }, { 
       "$and": [{ 
        "email": { 
         "$eq": "[email protected]" 
        } 
       }, { 
        "zipcode": { 
         "$eq": "11112" 
        } 
       }] 
      }] 
     }, 
     "rejectedPlans": [], 
     "namespace": "db.entries", 
     "winningPlan": { 
      "inputStage": { 
       "transformBy": { 
        "_id": false 
       }, 
       "inputStage": { 
        "filter": { 
         "$or": [{ 
          "$and": [{ 
           "email": { 
            "$eq": "[email protected]" 
           } 
          }, { 
           "zipcode": { 
            "$eq": "11111" 
           } 
          }] 
         }, { 
          "$and": [{ 
           "email": { 
            "$eq": "[email protected]" 
           } 
          }, { 
           "zipcode": { 
            "$eq": "11112" 
           } 
          }] 
         }] 
        }, 
        "direction": "forward", 
        "stage": "COLLSCAN" 
       }, 
       "stage": "PROJECTION" 
      }, 
      "stage": "SUBPLAN" 
     }, 
     "indexFilterSet": false, 
     "plannerVersion": 1 
    }, 
    "ok": 1.0, 
    "serverInfo": { 
     "host": "somehost", 
     "version": "3.4.6", 
     "port": 27017, 
     "gitVersion": "c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5" 
    } 
} 
+0

(.explain 'の出力を追加してください)' –

+0

@MarkusWMahlbergはOP – xtheking

+0

を参照してくださいクエリを使用すると、最終的には2つの文書を取得するには、文書の5453000を検討している、少し非効率的です。作成しない理由1.高カーディナリティを含むフィールドのいずれかにインデックスを作成すると、郵便番号または電子メールのいずれかになります。 2.集計パイプラインを使用して、索引の作成に使用したフィールドを使用して文書を選択し、新しい索引を使用して多数の文書をフィルターに掛けなければなりません。希望が役立ちます。 – Euclides

答えて

0

索引付けと再索引付けを避けるには(この問合せは電子メール/ zipだけでなく動的でもありません)、各ヘッダーのデータリストを作成して$in引数として使用してから、$and 。それは十分にうまくいっていると思われ、それは3分以上の時間を問い合わせていません。

例:

{'$and': [{'email': {'$in': ['[email protected]', '[email protected]', '[email protected]']}, 'zipcode': {'$in': ['12345', '11111', '11112']}}]} 
1

は、私はあなたの検索のための2つのフィールドを使用しているあなたの場合のように新しいインデックス(複合インデックス)を作成することをお勧め:以下.explain()の出力クエリでexplain()コマンドを追加してクエリを実行すると、COLLSCANではなくIXSCANが使用されていることがわかります。

関連する問題