2017-06-07 2 views
0

Ich benutze $ lookup in PyMongo, um zwei Sammlungen erfolgreich "beizutreten" (das funktioniert). Ich habe ein Problem, bei dem die zweite Sammlung, der ich beitrete, die BSON-Dokumentgröße überschreiten kann, wenn alle Datensätze zurückgegeben werden.MongoDB Aggregations Limit Lookup

Suche $ limit zu verwenden, um die Anzahl der Datensätze zu beschränken, die unter „match_docs“ zB dürfen teilnehmen: 100 Datensätze maximal aus „Kommentare“ pro OBJ_ID:

db.indicators.aggregate([ 
    { 
    "$lookup": { 
     "from": "comments", 
     "localField": "_id", 
     "foreignField": "obj_id", 
     "as": "match_docs" 
    } 
    } 
]) 

Ich habe versucht, verschiedene Arten von $ limit, und es scheint nur die Gesamtzahl der Ergebnisse insgesamt zu begrenzen, nicht nur für den Beitritt.

+0

Sie können kein Limit in $ Lookup gesetzt, aber Sie haben nicht diese die Abfrage Arbeit machen müssen. Das Hinzufügen von '{allowDiskUse: true}' zu Ihrer Aggregationsoption sollte das Problem beheben – felix

+0

@felix OP spricht über die BSON-Dokumentgrößenbeschränkung, nicht über das Speicherlimit. –

+1

Können Sie den Inhalt von '$ lookup' mit $ übereinstimmen, um die Ergebnisse zu reduzieren? Es gibt einen speziellen Fall, wenn die Pipelinestufen "$ lookup" -> "$ unload" -> "$ match" sind und die Bedingung in "$ match" (nacheinander) und "$ match" bezieht sich auf das Array von '$ lookup', wo die letzten zwei Stufen in den $ Lookup "gehisst" werden. Dies ist eine Optimierung, um die möglichen Einträge zu reduzieren. –

Antwort

1

Wenn Sie ein $unwind sofort tun, um ein $lookup folgenden wird die Pipeline optimiert werden, grundsätzlich die 2 Stufen Kombination hilft, die 16MB Grenze zu umgehen, die von den $lookup Rückkehr eine große Anzahl von Dokumenten führen könnten.

Beachten Sie, dass diese Optimierung nicht helfen kann, wenn ein einzelnes Dokument in der Fremdsammlung plus die Größe des Dokuments in der lokalen Sammlung 16 MB überschreitet.

+0

Beachten Sie auch, dass, wenn '$ unwind 'gefolgt von' $ match' folgt, die die fremde Sammlung adressiert, dann wird die Abfragebedingung auch zusammen mit der '$ unwind' in die' $ lookup' gehisst. Sie können dies mit '{" explain ": true}' als Argument zum Aggregieren sehen. –

+0

@NeilLunn gibt es einige Einschränkungen: https://jira.mongodb.org/browse/SERVER-21612. Um einen Index für das nachfolgende '$ match' zu verwenden, müssen Sie zusätzlich einen zusammengesetzten Index haben, der mit dem Feld beginnt, das für das' $ lookup' verwendet wird, gefolgt von dem/den Feld (en) im '$ match'. –

+0

Indizes haben nichts damit zu tun, was ich hier sage, und das ist ein separates Problem. Beide Antworten, die Sie hier gemacht haben, sehen aus, als würden sie von jemandem gemacht, der Begriffe in Google sucht, und könnten geklärt werden, um die ganze Geschichte mit einem Beispiel zu zeigen. –

1

Ich konnte es herausfinden.

$ Lookup -> $ Spiel -> $ Projekt

db.indicators.aggregate([{ 
    "$lookup": { 
     "from": "comments" 
     , "localField": "_id" 
     , "foreignField": "obj_id" 
     , "as": "match_docs" 
    } 
}, { 
    "$match": { 
     "match_docs": { 
      "$exists": True 
     } 
    } 
}, { 
    "$project": { 
     "match_docs_agg": { 
      "$slice": ["$match_docs", 3] 
     } 
    } 
}]) 
+1

Hassen Sie Ihre Blase dort platzen, aber das ist eigentlich nichts tun, um zu vermeiden, dass die BSON-Grenze gebrochen wird. Es ist auch ein "gegeben", um auf das Vorhandensein des Array-Feldes zu testen, da es "immer" in der Ausgabe zu "$ lookup" erzeugt wird.'$ slice' reduziert nur die Größe des Ergebnisses" nachdem "es bereits in das Dokument gezogen wurde, so dass das BSON-Limit immer noch gebrochen werden kann. Der einzige Grund, warum dies für Sie funktioniert, ist, weil die eingezogenen Dokumente dieses Limit nicht überschreiten. 16MB ist sowieso ziemlich viel –

+0

Sie sind 100% richtig, es tat was ich wollte in dem Sinne, dass es nur "3" der verbundenen Liste zurückgegeben wurde, aber es bricht immer noch während der Pipeline. – gleb1783

+0

Können Sie stattdessen bitte die Aggregation zeigen, die Sie in Ihrer Frage durchführen möchten. Mit Ihrer "Absicht" meine ich die "$ lookup" -Operation und die Aggregationsoperationen, die Sie mit den nächsten Informationen machen wollten, auch wenn es nur ein "$ slice" ist. Dann kann ich dir tatsächlich zeigen, was zu tun ist. –

Verwandte Themen