2015-01-01 3 views
2

나는 이런 식으로 뭔가를 찾고 몽고에 삽입 된 문서의 집합이 다른 구조체와 문서 : 나는 특정 보고서를 얻을 수를 조회 할쿼리 결과

type Stats struct { 
    UserStatus string `json:"userStatus" bson:"userStatus"` 
    ... a bunch more fields 
} 

type User struct { 
    ID    bson.ObjectId `json:"-" bson:"_id"` 
    LastName   string  `json:"lastName" bson:"lastName"` 
    FirstName  string  `json:"firstName" bson:"firstName"` 
    Role    string  `json:"role" bson:"role"` 
    Tags    []string  `json:"tags" bson:"tags"` 
    ... (a bunch more fields) 
    Stats   UserStats  `json:"stats" bson:"stats"` 
} 

을, 그래서 나는이 시도 :

func UserNameReport() { 
    ... get mongo session, etc. 

    // create struct of just the data I want returned 
    type UserNames struct { 
     LastName   string  `json:"lastName" bson:"lastName"` 
     FirstName  string  `json:"firstName" bson:"firstName"` 
     ... etc 
     UserStats  Stats   `json:"stats" bson:"stats"` 
    } 

    projection := bson.M{"lastName":1, "firstName":1, etc} 
    result := []UserNames{} 
    err := x.Find({query user collection}).Select(projection).All(&result) 
    ... 
} 

이 작품 - 내 질문은 어떻게 '통계'구조체에서 단 하나의 필드를 포함 할 수 있습니까? 즉, 나는 본질적으로 "투사"이되고 싶어 :

projection := bson.M{"lastName":1, ..., "stats.userStatus":1} <-- stats.userStatus doesn't work 
... 
err := x.Find({query user collection}).Select(projection).All(&result) 

내가 얻는 결과에 구조체 포함 된 전체 "통계"- 나는 하위 문서에서 단 하나의 필드를 필터링 할 수있는 방법 결과 집합에 넣으시겠습니까?

감사합니다.

답변

1

그것은 MongoDB를 함께 나를 위해 완벽하게 작동 2.6.5

다음 코드에서

package main 

import (
    "fmt" 
    "gopkg.in/mgo.v2" 
    "gopkg.in/mgo.v2/bson" 
    "log" 
) 

type Statistics struct { 
    Url string 
    Hits int 
} 

type Person struct { 
    Num int 
    Uuid string 
    Name string 
    Stats []Statistics 
} 

func main() { 

    // Connect to the database 
    session, err := mgo.Dial("localhost") 
    if err != nil { 
     panic(err) 
    } 
    defer session.Close() 

    // Remove people collection if any 
    c := session.DB("test").C("people") 
    c.DropCollection() 

    // Add some data 
    err = c.Insert(
     &Person{1, "UUID1", "Joe", []Statistics{Statistics{"a", 1}, Statistics{"b", 2}}}, 
     &Person{2, "UUID2", "Jane", []Statistics{Statistics{"c", 3}, Statistics{"d", 4}}}, 
     &Person{3, "UUID3", "Didier", []Statistics{Statistics{"e", 5}, Statistics{"f", 6}}}) 
    if err != nil { 
     log.Fatal(err) 
    } 

    result := []Person{} 
    err = c.Find(bson.M{"$or": []bson.M{bson.M{"uuid": "UUID3"}, bson.M{"name": "Joe"}}}).Select(bson.M{"num": 1, "name": 1, "stats.hits": 1}).All(&result) 
    if err != nil { 
     log.Fatal(err) 
    } 

    fmt.Println(result) 
} 

결과 :

내가 무엇을 기대 정확하게
[{1 Joe [{ 1} { 2}]} {3 Didier [{ 5} { 6}]}] 

... .

0

어쩌면 다른 사람들에게 도움이 될 것입니다. 본질적으로 저는 임베디드 된 문서로 문서를 가져 와서 select a.LastName + ', + a.FirstName as Name, b. 다른 데이터와 본질적으로 다른 '테이블'/ '문서'가 있습니다.

여기 내 현재 해결책이 있습니다. 더 나은 것을 얻는 것을 좋아합니다 (더 실적이 좋습니까?).

나는 새로운 구조체를 만들어 나는

import "github.com/goinggo/mapstructure" 


type Stats struct { 
    UserStatus string `json:"userStatus" bson:"userStatus"` 
    ... a bunch more fields 
} 

type User struct { 
    ID    bson.ObjectId `json:"-" bson:"_id"` 
    LastName   string  `json:"lastName" bson:"lastName"` 
    FirstName  string  `json:"firstName" bson:"firstName"` 
    Role    string  `json:"role" bson:"role"` 
    Tags    []string  `json:"tags" bson:"tags"` 
    ... (a bunch more fields) 
    Stats   UserStats  `json:"stats" bson:"stats"` 
} 


type MyReportItem struct { 
    FirstName string `json:"firstName" jpath:"firstName"` 
    LastName string `json:"lastName" jpath:"lastName"` 
    Status  string `json:"status" jpath:"stats.userStatus"` 
} 

type MyReport struct { 
    Results []MyReportItem `json:"results"` 
} 


func xxxx(w http.ResponseWriter, r *http.Request) { 

    var users MyReportItem 

    // the results will come back as a slice of map[string]interface{} 
    mgoResult := []map[string]interface{}{} 

    // execute the query 
    err := c.Find(finder).Select(projection).All(&mgoResult) 
    if err != nil { 
     http.Error(w, err.Error(), http.StatusInternalServerError) 
     return 
    } 

    user := MyReportItem{} 
    // iterate through the results and decode them into the MyReport struct 
    for _, x := range mgoResult { 
     docScript, _ := json.Marshal(x) 
     docMap := map[string]interface{}{} 
     json.Unmarshal(docScript, &docMap) 

     err := mapstructure.DecodePath(docMap, &user) 
     if err == nil { 
     users.Results = append(users.Results, user) 
    } 
    } 

    ... send back the results ... 
    _ := json.NewEncoder(w).Encode(&users) 
} 

지금 내가 형태로 객체의 조각을 얻는 'mapstructure'라이브러리를 사용하고 있습니다 :

results: [ 
    { 
    firstName: "John", 
    lastName: "Doe", 
    status: "active" 
    } 
    ... 
] 

대신 :

{ 
    firstName: "John", 
    lastName: "Doe", 
    stats: { 
      status: "active" 
      } 
}