2016-11-08 4 views
3

mgoパッケージを使用してgo(golang)のmongoDBクエリの1つに$lookupの機能を実装しようとしています。MongoDB Go(mgo.v2)の集計検索

以下

は私のコレクションです:

フォルダ:

"_id" : ObjectId("22222222222222"), 
"name" : "Media", 
"level" : 1, 
"userIDs": [ObjectId("4444444444444")] 

書類:以下

"_id"  : ObjectId("11111111111111"), 
"title" : "Media Management", 
"body"  : BinData(0,"PvQ6z2NBm4265duo/e2XsYxA5bXKo="), 
"level" : 1, 
"folderID" : ObjectId("22222222222222"), // Foreign Key/Field 
"userIDs" : [ObjectId("44444444444444")] 

に成功シェル上で実行され、私が書いたクエリです。

var query = [ 
{ 
    "$lookup": { 
    "from":   "documents", 
    "localField": "_id", 
    "foreignField": "folderID", 
    "as":   "documents", 
    } 
} 
,{ 
    "$match": { 
     "userIDs": ObjectId("userIdHere"), // filder by a userID 
     "level": {$gte: 0},    // filter by a folder level 
    }, 
    } 
]; 

db.folders.aggregate(query).pretty().shellPrint(); 

このスクリプトをシェルで実行すると、目的の結果が得られます。基本的にfolderコレクションはでリンクされた完全なdocumentsを含む私に返されます。この質問はすでに長すぎると思われるので、私はここには含めません。

私はこのクエリをmgoが解析して実行できるものに変換しようとしました。ここでは、外出先のコードで以下の通りです:

query := bson.M{ 
    "$lookup": bson.M{ // lookup the documents table here 
    "from":   "documents", 
    "localField": "_id", 
    "foreignField": "folderID", 
    "as":   "documents", 
}, 
    "$match": bson.M{ 
    "level": bson.M{"$gte": user.Level}, // filter by level 
    "userIDs": user.ID,     // filter by user 
    }, 
} 

pipe := collection.Pipe(query) // querying the "folders" collection 
err := pipe.All(&result) 

私はいつも同じエラーを取得:私が正しく理解していれば、それはできないので、それはだフィールドの間違ったタイプ(パイプラインに)3 = 4

を!結果を$ resultオブジェクトに適切に解析します。私は構造体が必要な構造を確実に持つことを保証するためにできることはすべて尽くしました。また、私はgenereric []interface{}と空のbson.M{}オブジェクトを渡そうとしました。同じエラーが表示されます。

type Folder struct { 
    ID  bson.ObjectId `json:"id" bson:"_id"` 
    Name  string   `json:"name"` 
    Level  int    `json:"level"` 
    UserIDs []bson.ObjectId `json:"userIDs" bson:"userIDs"` 
    Users  []User   `json:"-" bson:"-"` // doesn't get stored in the database 
    Documents []Document  `json:"-" bson:"-"` // doesn't get stored in the database 
} 

は、私も、私は全然戻ってその$lookupクエリから何かを得ることができるかどうかを確認するために$match句を削除しました:

以下は私のフォルダ構造体です。しかし、私はまだ同じエラーが発生します。

おそらく、mgoパッケージは$lookupをサポートしていませんか?もしそうなら、別の方法がありますか? おそらく、生のクエリテキストをmongoに送信し、生の応答を受け取り、それを自分で解析することができましたか?

答えて

4

解決策を見つけました!

トリックがスライス([]bson.M)でクエリを作成し、クエリの構造を少し変更しました:

query := []bson.M{{ 
    "$lookup": bson.M{ // lookup the documents table here 
    "from":   "documents", 
    "localField": "_id", 
    "foreignField": "folderID", 
    "as":   "documents", 
    }}, 
    {"$match": bson.M{ 
    "level": bson.M{"$lte": user.Level}, 
    "userIDs": user.ID, 
}}} 

pipe := collection.Pipe(query) 
err := pipe.All(&folders) 

私はmgo's Pipe function docsで手がかりを見つけました。今

type Folder struct { 
    ID  bson.ObjectId `json:"id" bson:"_id"` 
    Name  string   `json:"name"` 
    Level  int    `json:"level"` 
    UserIDs []bson.ObjectId `json:"userIDs" bson:"userIDs"` 
    Users  []User   `json:"-" bson:"-"` // doesn't get stored in the database 
    Documents []Document  // `json:"-" bson:"-" Removed this so that mgo can unmarshal 
          // the documents correctly 
} 

私はちょうど私のデータベースにDocumentsフィールドを格納しないための方法を把握する必要があります。また、私はその場をpupolateするのMgOのための私のFolders構造体にDocumentsフィールドのタグを変更する必要がありましたFolderを保存します。