2017-05-24 35 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 } 

我遇到的問題是$ project階段的$ ifNull。

如何使用mgo包在Go中構建$ ifNull行?

我試着用:

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

,但它始終返回news_count字段爲空字符串。

任何幫助,非常感謝!

EDIT [解決]:

的問題是愚蠢的,我曾經爲news_count場錯誤type在轉到struct

爲了完整起見,在圍棋的管道是:

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' –

回答

0

news_count投影作品,錯誤的是別的地方的代碼,你的天堂」 t張貼。

看到這個完整,工作示例:

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")]