2016-06-22 14 views
2

Ich habe> 8000 Datensätze in meinem DB und dies ist einer von ihnen:MongoDB, PyMongo - Aggregat mit Fund Bedingungen

{ 
    "_id" : ObjectId("57599c498c39598eafb781b9"), 
    "_class" : "vn.cdt.entity.db.AccessLog", 
    "url" : "/shop/huenguyenshop/browse", 
    "ip" : "10.0.0.238", 
    "sessionId" : "86E5CF8E6D465A6EDFE7C9BF7890AA4B", 
    "oldSessionId" : "86E5CF8E6D465A6EDFE7C9BF7890AA4B", 
    "cookie" : "{\"sessionId\":\"86E5CF8E6D465A6EDFE7C9BF7890AA4B\",\"objects\":[{\"id\":\"903815555908\",\"type\":\"VIEW_SHOP\",\"count\":1}]}", 
    "isCookie" : true, 
    "createTime" : NumberLong(1464935913641), 
    "objectId" : "903815555908", 
    "type" : "VIEW_SHOP" 
} 

Was ich tun möchte:

Ich möchte alle finden Aufzeichnung haben gleiche oldSessionId mit (type: VIEW_ITEModertype: BUY_ITEM) und createTime ist neueste.

Was ich versucht hatte:

pipeline = ([ 
       {"$group" : { "_id": "$oldSessionId", "count": { "$sum": 1 } }}, 
       {"$match": {"count" : {"$gt": 1} } }, 
       {"$project": {"oldSessionId" : "$_id", "_id" : 0} } 
      ]) 

Aber das pipeline gib mir nur sessionId

find({'createTime': {'$lt':1464419127000, '$gt':1464332727000}, 
'$or':[{'type':'BUY_ITEM'},{'type':'VIEW_ITEM'}]}) 

Das find geben Sie mir alle Datensätze mit type: VIEW_ITEModertype: BUY_ITEM in bestimmten Zeitpunkt.

Ich weiß nicht, wie Filter mit type und createTime hinzufügen, um zu bekommen, was ich will.

aktualisieren Dank @chridam mir geholfen:

Wenn i bestimmten Datum Aggregation hinzugefügt werden soll, kann ich Abfrage wie folgt hinzufügen machen:

pipeline = \ 
    (
     [ 
      { "$match": { 
         "createTime": {"$lt":1464419127000, "$gt":1464332727000 }, 
         "type": { "$in": ["VIEW_ITEM", "BUY_ITEM"] } 
         } 
      }, 
      { "$sort": { "createTime": -1, "oldSessionId": 1 } }, 
      { 
       "$group": 
        { "_id": "$oldSessionId", 
         "_class": { "$first": "$_class" }, 
         "url": { "$first": "$url" }, 
         "ip": { "$first": "$ip" }, 
         "sessionId": { "$first": "$sessionId" }, 
         "oldSessionId": { "$first": "$oldSessionId" }, 
         "cookie": { "$first": "$cookie" }, 
         "isCookie": { "$first": "$isCookie" }, 
         "createTime": { "$first": "$createTime" }, 
         "objectId": { "$first": "$objectId" }, 
         "type": { "$first": "$type" }, 
        } 
      } 

     ] 

    ) 

Antwort

1

alle Dokumente zu erhalten, die haben das gleiche oldSessionId mit (Typ: VIEW_ITEM oder Typ: BUY_ITEM) und createTime ist am längsten, müssen Sie eine Aggregation Pipeline zeigen, die die folgenden Akteure (Stufen) hat:

  1. $match Stufe:

    • Dadurch wird alle Dokumente filtert, die eine Art von entweder VIEW_ITEM oder BUY_ITEM haben. Sie können den Operator $in mit der Abfrage verwenden, da Sie die Dokumente auswählen können, bei denen der Wert des Felds type einem beliebigen Wert des angegebenen Arrays entspricht, bei dem es sich um eine Liste mit den zwei möglichen Typenwerten handelt, d. H. ["VIEW_ITEM", "BUY_ITEM"].
  2. $sort Bühne

    • dies die Dokumente aus der vorherige Pipeline leisten wird (siehe oben) bestellt werden. Dies ist erforderlich, weil Sie diese gefilterten Dokumente im letzten Feld createTime aggregieren möchten.
  3. $group Bühne

    • In diesem letzten Schritt gruppieren Sie alle bestellten Dokumente, die von der oldSessionId Schlüssel, fügen Sie die Felder, die $first Operator wollen.

alle oben genannten Rohre Piecing zusammen die folgende Aggregation Pipeline zu bilden:

pipeline = [ 
    { "$match": { "type": { "$in": ["VIEW_ITEM", "BUY_ITEM"] } } }, 
    { "$sort": { "createTime": -1, "oldSessionId": 1 } }, 
    { 
     "$group": { 
      "_id": "$oldSessionId", 
      "_class": { "$first": "$_class" }, 
      "url": { "$first": "$url" }, 
      "ip": { "$first": "$ip" }, 
      "sessionId": { "$first": "$sessionId" }, 
      "cookie": { "$first": "$cookie" }, 
      "isCookie": { "$first": "$isCookie" }, 
      "createTime": { "$first": "$createTime" }, 
      "objectId": { "$first": "$objectId" }, 
      "type": { "$first": "$type" }, 
     } 
    } 
] 
+0

wieder helfen Sie mir mein Problem gelöst. Vielen Dank @chridam. '" cookie ":: {" $ first ":" $ cookie "}' hat zwei ":" nach "cookie". '" Cookie ": {" $ first ":" $ cookie "}'. Wenn ich '.count()' hinter 'aggregate (pipeline)' lege, wird der show error 'TypeError: db.getCollection (...). Aggregate (...). Count ist keine Funktion: @ (shell): 1: 1' Wie kann ich die Nummer des Datensatzes nach der Aggregation überprüfen? –

+0

Vielen Dank, dass Sie den Tippfehler bemerkt haben, und Sie sind willkommen, immer glücklich zu helfen :) Wie bei der Folgeabfrage hat die 'aggregate()' Methode keine 'count()' Methode, sie wird nur auf der Suche gefunden (), so können Sie die Funktion nicht auf aggregate() 'anwenden. Scheint wie ein neues Problem, was du erreichen willst, kannst du bitte eine neue Frage dafür erstellen? – chridam

+0

Ich benutzte Pymongo und mache eine Schleife, um die Anzahl der Dokumente zu zählen. Und seine Show ist in Ordnung! –

Verwandte Themen