如何检索 []bson.M 类型的地图

How to retrieve []bson.M type of map

如何检索多维[]bson.M类型的地图

mongo中的数据就像

"taskData" : { 
    "createdOn" : ISODate("2016-02-20T21:23:11.903Z"), 
    "Task_content" : "@bob", 
    "Priority" : "2", 
    "owner_Uname" : "alice"
}

我试图访问它的代码

var n []bson.M
 e := collection.Find(bson.M{"users."+strconv.Itoa(j)+".user_name" :   r.FormValue("value[userName]")}).Select(bson.M{"taskData.owner_Uname":1,"_id":0}).All(&n)
if e != nil {
   fmt.Println("Error : ",e)
}else{
   fmt.Println(n[0]["taskData"])
}

得到这样的输出

map[owner_Uname:alice]

我需要用另一个查询访问这个结果字符串。 这是我试图将其转换为简单地图的界面 newMap :=n[0]["taskData"].(map[string]interface{})但它给我一个运行时错误interface conversion: interface {} is bson.M, not map[string]interface {}

result := rawData{}
err := collection.Find(bson.M{"user_name":n[0]["taskData"]["owner_Uname"]}).All(&result)

现在我想在上面的查询中使用它... 请帮帮我。提前致谢

编辑:- mongo中的数据就像

{
   "_id" : ObjectId("56bf128f5a9a6a0ebfdd5075"),
     "deadLine" : {
       "Start_time" : ISODate("2016-05-24T00:00:00Z"),
       "End_time" : ISODate("2016-05-29T00:00:00Z")
     },
   },
   "taskData" : { 
       "createdOn" : ISODate("2016-02-20T21:23:11.903Z"), 
       "Task_content" : "@bob", 
       "Priority" : "2", 
       "owner_Uname" : "alice"
   },
   "group" : {
      "1" : {
        "grp_name" : "grp"
       },
      "2" : {
        "grp_name" : "secondGrp"
       }
    }

如果在结构中使用嵌套结构或映射完成,那对我也有用

我将提供一个通用示例来帮助您理解,因为 SO 不是免费的编码服务,而是一个同行互相帮助掌握问题的平台。

我的方法是完全不使用 bson.M 作为返回值。

package main

import (
    "fmt"
    "time"

    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

type Baz struct {
    Date  time.Time
    Value int
}

type Bar struct {
    Name string
    Baz  []Baz
}

type Foo struct {
    Owner  string
    hidden int
    Bar    Bar
}

const (
    ds   = "localhost:27017"
    db   = "test"
    coll = "nestdemo"
)

func main() {

    o := Foo{
        Owner:  "me",
        hidden: 1,
        Bar: Bar{
            Name: "funky",
            Baz: []Baz{
                Baz{Date: time.Now(), Value: 42},
            },
        },
    }

    // CHECK ERRORS in production environments
    conn, _ := mgo.Dial(ds)
    defer conn.Close()

    c := conn.DB(db).C(coll)
    c.Insert(o)

    l := &Foo{}

    c.Find(bson.M{"owner": "me"}).One(l)

    fmt.Printf("Loaded data: %+v\n", l)
    fmt.Printf(
        "You got your answer to life, the universe and all the rest at %s: %d\n",
        l.Bar.Baz[0].Date.Format(time.Kitchen), l.Bar.Baz[0].Value,
    )
}

您可以在您的本地计算机上 运行 这个程序(根据需要调整常量),它应该给您一个如下所示的输出:

$ go run main.go 
Loaded data: &{Owner:me hidden:0 Bar:{Name:funky Baz:[{Date:2016-02-24 09:00:06.471 +0100 CET Value:42}]}}
You got your answer to life, the universe and all the rest at 9:00AM: 42

相应集合中的条目应如下所示:

{
  "_id" : ObjectId("56cd6306538ba56563bdab76"),
  "owner" : "me",
  "bar" : {
    "name" : "funky",
    "baz" : [
      {
        "date" : ISODate("2016-02-24T08:00:06.471Z"),
        "value" : 42
      }
    ]
  }
}

这里有几点需要注意。

  1. 我不需要结构定义中的单个字符来将结构编组到 BSON 和从 BSON 编组。它是由 mgo according to the rules described in the docs 自动完成的。但是,您可以自定义(非)封送处理的行为,如此处所述。
  2. 未导出的字段(本例中的hidden)在解组时取零值——记住这一点,它可能会咬你的脖子。
  3. 无需使用 bson.M 来处理您的数据,这让生活变得更加轻松 – 例如,无需手动类型转换。

总而言之:您需要做的就是创建一个可以将数据解组到其中的结构。然后您可以像往常一样访问各个字段,而无需修改字符串等。正如您所见,这只是一点点工作,但相当微不足道。

注意:您展示的数据模型在句法和概念上都不正确。暂时搁置前者:将值作为键是一种非常糟糕的做法,如 group 子文档所示。这将始终迫使您来回处理字符串解析,使您的 MongoDB 生活变得像开发人员一样复杂。

我的上述建议假设您将其更正为:

{
…
  groups:[
    {grp_id: 1, grp_name: "grp"},
    {grp_id: 2, grp_name: "secondGrp"}
  ]
…
}