duanmie9741 2016-02-21 00:43
浏览 97
已采纳

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

How to retrieve multidimensional []bson.M type of map

The data in mongo is like

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

The code through which i tried to access it

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

getting output like this

map[owner_Uname:alice]

I need to access this resultant string with another query. It is a interface i tried to convert it to simple map newMap :=n[0]["taskData"].(map[string]interface{})but it gives me an runtime error 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)

Now I want to use it in above query ... Kindly help me out. Thanks in advance

Edit :- The data in mongo is like

{
   "_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"
       }
    }

That will work me too if it is done with nested struct or map in struct

  • 写回答

1条回答 默认 最新

  • duanping6698 2016-02-24 08:39
    关注

    I'll provide you with a general example to help you understand, since SO is not a free coding service, but a platform where peers help each other to take a grasp on the problem.

    My approach is not to use bson.M at all for the returned value.

    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
    ", l)
        fmt.Printf(
            "You got your answer to life, the universe and all the rest at %s: %d
    ",
            l.Bar.Baz[0].Date.Format(time.Kitchen), l.Bar.Baz[0].Value,
        )
    }
    

    You can run this program on you local machine (with the constants adjusted as needed), which should give you an output looking like this:

    $ 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
    

    The entry in the according collection should read something like this:

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

    A few things are to note here.

    1. I didn't need a single character in my struct definitions to have the structs marshaled to and marshaled from BSON. It was done automagically by mgo according to the rules described in the docs. However, you can customize the behavior of the (un-)marshaling, as described there.
    2. Unexported fields (hidden in this example) take their zero value upon unmarshalling – keep that in mind, it can bite you in the neck.
    3. There is no need to use bson.M to handle your data, which makes life a lot easier – no manual type conversions, for example.

    In summary: All you need to do is to create a struct your data can be unmarhaled into. Then you can access the various fields as usual, without string fiddling and alike. That's bit of work, but a rather trivial one, as you can see.

    Note: The data model you have shown is both syntactically and conceptually incorrect. Setting aside the former for now: It is a very bad practice to have values as keys, as shown in the group subdoc. This will always force you to deal with string parsing back and forth, making your life with MongoDB as complicated as it can get as a developer.

    My above suggestion assumes you will correct that into something like:

    {
    …
      groups:[
        {grp_id: 1, grp_name: "grp"},
        {grp_id: 2, grp_name: "secondGrp"}
      ]
    …
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计