使用mgo管道功能时未完全检索到数据

I was using pipe function in mgo to retrieve data. My data structs are as follows.

type Company struct {
    Id              bson.ObjectId `bson:"_id,omitempty"`
    CompanyName     string
    Slug            string
    CompanyUsers    []CompanyUser
}
type CompanyUser    struct {
    UserName    string
    Email       string
    FullName    string
}

I needed to check whether a given "UserName" is present under "CompanyUsers" in a "Company" with a given "Slug".

Both Slug and UserName are provided by the User.

Using Pipe function I successfully done the search, but the data is returned with an empty CompanyUsers array.

My query is as follows:

var companyResults []Company

pipeline := []bson.M{
    {"$match": bson.M{"slug": slug}},
    {"$unwind": "$companyusers"},
    {"$match": bson.M{
        "companyusers.username": username,
    }},
}
err := c.Pipe(pipeline).All(&companyResults)

This provides me a search result as follows:

[{ObjectIdHex("573aa0fddd731711c94830ca") MyCompany companyslug [] }]

None of the data in CompanyUsers are retrieved. How can I solve this error?

Try making companyResults a []map[string]interface{} instead of a []Company to see what sort of a result you get. This helps to figure out what the structure of companyResults should be.

var companyResults []map[string]interface{}

You will see a result like,

[map[companyname:MyCompany slug:companyslug companyusers:map[username:username] _id:test]]

See that companyusers is infact a map not an array. This is because your usage of the $unwind stage. It deconstructs the array, outputting one document for each element in the array. See docs.

I agree with John Smith's answer, that you do not need pipelines at all. But following should give you the desired result.

type Result struct {
    Id           string `bson:"_id,omitempty"`
    CompanyName  string
    Slug         string
    CompanyUsers CompanyUser
}

var companyResults []Result

I might be missing something, but why do you need Pipe for this?

You probably could do it easier:

query := bson.M{"slug": slug, "companyusers.username": username}

err := c.Find(query).All(&companyResults)

I'm fairly certain this would give you the same results.

However, the main problem is you didn't give the bson marshaller the fields name. Since the field in your database is companyusers and username you'll have to tell that to the marshaller.

type Company struct {
    Id              bson.ObjectId `bson:"_id,omitempty"`
    CompanyName     string
    Slug            string
    CompanyUsers    []CompanyUser `bson:"companyuser"`
}
type CompanyUser    struct {
    UserName    string `bson:"username"`
    Email       string
    FullName    string
}

You probably want to fix that for the rest of the fields as well.