2017-05-24 8 views
1

私はmongoコンソールからGoコードにクエリを移植するのに苦労しています。 MongoDBの新機能ですので、私が考慮していない追加の間違いがあるかもしれません。

サンプルデータ 'ユーザー' コレクション:

{ "_id" : ObjectId("592400188d84961b7f34b0cd"), "username" : "randomUser2", "location" : { "type" : "Point", "coordinates" : [ -17.282573, 63.755657 ] } } 
{ "_id" : ObjectId("592400188d84961b7f34b0ce"), "username" : "randomUser1", "location" : { "type" : "Point", "coordinates" : [ -17.634135, 65.705665 ] } } 

サンプルデータ 'newscounter' コレクション:

{ "_id" : ObjectId("592400188d84961b7f34b0cd"), "count" : 14 } 

はモンゴでクエリは次のようになります。

db.users.aggregate([ 
    { $geoNear: { 
     near: { type: "Point", coordinates: [-21.861198,64.120877] }, 
     distanceField: "distance", 
     maxDistance: myDistance * 1000, 
     spherical: true } 
    }, 
    { 
     $sort: { "distance": 1 } 
    }, 
    { 
    $lookup: { 
     from: "newscounter", 
     localField: "_id", 
     foreignField: "_id", 
     as: "news_count" } 
    }, 
    { 
     $unwind: { path: "$news_count", preserveNullAndEmptyArrays: true } 
    }, 
    { 
     $project : { 
      "id": 1, 
      "username": 1, 
      "distance": 1, 
      "news_count": { $ifNull : ["$news_count.count", 0] } 
     } 
    } 
]) 

出力されます(ここでは、計算された距離フィールドにランダム値を使用しました):

{ "_id" : ObjectId("592400188d84961b7f34b0cd"), "username" : "randomUser2", "distance" : 123, "news_count" : 14 } 
{ "_id" : ObjectId("592400188d84961b7f34b0ce"), "username" : "randomUser1", "distance" : 456, "news_count" : 0 } 

私が困っている部分は、$プロジェクト段階の$ ifNullです。

Goでmgoパッケージを使用して$ ifNull行を作成するにはどうすればよいですか?

私が試した:

"news_count": bson.M{ 
    "$ifNull": [2]interface{}{"$news_count.count", 0}, 
} 

が、それは常にnews_countフィールドに空の文字列を返します。

ご協力いただきありがとうございます。

EDIT [解決]:

問題は、私が行くstructnews_countフィールドに間違ったtypeを持っていた、愚かでした。完全を期すために

移動中のパイプラインは次のとおりです。

p := []bson.M{ 
     bson.M{ 
      "$geoNear": bson.M{ 
       "near":   bson.M{"type": "Point", "coordinates": center}, 
       "distanceField": "distance", 
       "maxDistance": maxDistance, 
       "spherical":  true, 
      }, 
     }, 
     bson.M{ 
      "$sort": bson.M{ 
       "distance": 1, 
      }, 
     }, 
     bson.M{ 
      "$lookup": bson.M{ 
       "from":   "newscount", 
       "localField": "_id", 
       "foreignField": "_id", 
       "as":   "news_count", 
      }, 
     }, 
     bson.M{ 
      "$unwind": bson.M{ 
       "path": "$news_count", 
       "preserveNullAndEmptyArrays": true, 
      }, 
     }, 
     bson.M{ 
      "$project": bson.M{ 
       "_id":  1, 
       "username": 1, 
       "distance": 1, 
       "news_count": bson.M{ 
        "$ifNull": []interface{}{"$news_count.count", 0.0}, 
       }, 
      }, 
     }, 
    } 

結果struct

type Result struct { 
      ID  bson.ObjectId `json:"id" bson:"_id"` 
      Username string   `json:"username" bson:"username"` 
      Distance int64   `json:"distance" bson:"distance"` 
      NewsCount int64   `json:"news_count" bson:"news_count"` 
     } 
+0

右のようです。キックのために '[] interface {} {" $ news_count "、0}'はどうでしょうか?それに失敗すると、パイプライン全体の再生のコンテキストで表示できますか。もっと重要なことは、 '$ unwind'が正しいことをしていることでしょうか? –

+0

同じ結果、私はすでにそれを試みていました。私は$ unwindを追加しないと結果は '{" _id ":ObjectId(" 5924001e8d84961b7f34b111 ")、" username ":" xyz "、" distance ":123、" news_count ":[{" count ":14} ]} {"_id":ObjectId( "5924001d8d84961b7f34b104")、 "username": "abc"、 "distance":123、 "news_count":[]} ' そして私は単一のフィールドを持っています。アレイ。 – GreyHands

+0

Doh。あなたはコメントを編集してうれしいです。今問題は明らかです。'$ lookup'の結果として1つの結果しかありません –

答えて

0

あなたnews_count投影作品、エラーは「はあなたの避難所コードのどこかで投稿されました。

は、このフル、実施例を参照してください。

cu := sess.DB("").C("users") 
cnc := sess.DB("").C("newscounter") 

he := func(err error) { 
    if err != nil { 
     panic(err) 
    } 
} 

he(cu.Insert(
    bson.M{ 
     "_id":  bson.ObjectIdHex("592400188d84961b7f34b0ce"), 
     "username": "randomuser1", 
     "location": bson.M{ 
      "type":  "Point", 
      "coordinates": []interface{}{-17.634135, 65.705665}, 
     }, 
    }, 
    bson.M{ 
     "_id":  bson.ObjectIdHex("592400188d84961b7f34b0cd"), 
     "username": "randomuser2", 
     "location": bson.M{ 
      "type":  "Point", 
      "coordinates": []interface{}{-17.282573, 63.755657}, 
     }, 
    }, 
)) 
he(cnc.Insert(
    bson.M{ 
     "_id": bson.ObjectIdHex("592400188d84961b7f34b0cd"), 
     "count": 14, 
    }, 
)) 

pipe := cu.Pipe([]bson.M{ 
    { 
     "$geoNear": bson.M{ 
      "near": bson.M{ 
       "type":  "Point", 
       "coordinates": []interface{}{-21.861198, 64.120877}, 
      }, 
      "distanceField": "distance", 
      "maxDistance": 123456789, 
      "spherical":  true, 
     }, 
    }, 
    { 
     "$sort": bson.M{"distance": 1}, 
    }, 
    { 
     "$lookup": bson.M{ 
      "from":   "newscounter", 
      "localField": "_id", 
      "foreignField": "_id", 
      "as":   "news_count", 
     }, 
    }, 
    { 
     "$unwind": bson.M{ 
      "path": "$news_count", 
      "preserveNullAndEmptyArrays": true, 
     }, 
    }, 
    { 
     "$project": bson.M{ 
      "id":  1, 
      "username": 1, 
      "distance": 1, 
      "news_count": bson.M{ 
       "$ifNull": []interface{}{"$news_count.count", 0}, 
      }, 
     }, 
    }, 
}) 

it := pipe.Iter() 

fmt.Println() 
m := bson.M{} 
for it.Next(&m) { 
    fmt.Println(m) 
    fmt.Println() 
} 
he(it.Err()) 

出力:

map[_id:ObjectIdHex("592400188d84961b7f34b0cd") username:randomuser2 distance:227534.08191011765 news_count:14] 

map[username:randomuser1 distance:266222.98643136176 news_count:0 _id:ObjectIdHex("592400188d84961b7f34b0ce")]