Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Golang mongodb mgo驱动程序Upsert/UpsertId文档_Mongodb_Go_Mgo - Fatal编程技术网

Golang mongodb mgo驱动程序Upsert/UpsertId文档

Golang mongodb mgo驱动程序Upsert/UpsertId文档,mongodb,go,mgo,Mongodb,Go,Mgo,报告说: 如果参数仅包含更新运算符表达式,则和参数的字段和值。更新将根据参数中的相等子句创建基础文档,然后应用参数中的更新表达式 报告说: Upsert查找与提供的选择器文档匹配的单个文档,并根据更新文档对其进行修改。如果未找到与选择器匹配的文档,则更新文档将应用于选择器文档,并将结果插入到集合中 但如果我这样做: session.UpsertId(data.Code, data) 最后我得到了一个条目,它有一个由mongodb自动生成的ObjectID,而不是data.Code 这意味着Up

报告说:

如果参数仅包含更新运算符表达式,则和参数的字段和值。更新将根据参数中的相等子句创建基础文档,然后应用参数中的更新表达式

报告说:

Upsert查找与提供的选择器文档匹配的单个文档,并根据更新文档对其进行修改。如果未找到与选择器匹配的文档,则更新文档将应用于选择器文档,并将结果插入到集合中

但如果我这样做:

session.UpsertId(data.Code, data)
最后我得到了一个条目,它有一个由mongodb自动生成的ObjectID,而不是data.Code

这意味着UpsertId希望数据使用update运算符格式化,而您不能使用任意结构?或者我在这里错过了什么

警察局。Mongo 2.4.9 mgo v2 golang go版本devel+f613443bb13a

编辑:

这是我的意思示例,使用Neil Lunn的示例代码:

package main

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

type Person struct {
  Code string
  Name  string
}

func main() {
  session, err := mgo.Dial("admin:admin@localhost");

  if err != nil {
        fmt.Println("Error: ", err)
        return
    // panic(err)
  }

  defer session.Close()

  session.SetMode(mgo.Monotonic, true)

  c := session.DB("test").C("people")

  var p = Person{
    Code: "1234",
    Name: "Bill",
  }

  _, err = c.UpsertId( p.Code, &p )

  result := Person{}
  err = c.FindId(p.Code).One(&result)
  if err != nil {
        fmt.Println("FindId Error: ", err)
        return
    // panic(err)
  }

  fmt.Println("Person", result)

}

您似乎在谈论使用自定义
\u id
字段分配结构。这实际上取决于如何定义结构。下面是一个简单的例子:

package main

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

type Person struct {
  ID    string `bson:"_id"`
  Name  string
}

func main() {
  session, err := mgo.Dial("127.0.0.1");

  if err != nil {
    panic(err)
  }

  defer session.Close()

  session.SetMode(mgo.Monotonic, true)

  c := session.DB("test").C("people")

  var p = Person{
    ID: "1",
    Name: "Bill",
  }

  _, err = c.UpsertId( p.ID, &p )

  result := Person{}
  err = c.Find(bson.M{"_id": p.ID}).One(&result)
  if err != nil {
    panic(err)
  }

  fmt.Println("Person", result)

}
因此,在这里的自定义定义中,我将ID字段映射到bson
\u ID
,并将其类型定义为string。如示例所示,这正是通过UpsertId序列化然后检索时发生的情况


现在您已经详细阐述了,我将指出
struct
定义上的差异

我所做的是:

{ "_id": 1, "name": "Bill" }
您所拥有的(在结构上没有相同的映射)将执行以下操作:

{ "_id": ObjectId("53cfa557e248860d16e1f7e0"), "code": 1, "name": "Bill" }
如您所见,upsert中给出的
\u id
将永远不会匹配,因为结构中没有任何字段映射到
\u id
。你需要和我一样的东西:

type Person struct {
    Code string `bson:"_id"`
    Name string
}

将字段映射到必填的
\u id
字段,否则会自动为您生成一个。

我发现MongoDB的文档是正确的。正确的方法是将要插入的结构包装到更新操作符中

Neil Lunn提供的示例代码如下所示:

package main

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

type Person struct {
  Code string
  Name  string
}

func main() {
  session, err := mgo.Dial("admin:admin@localhost");

  if err != nil {
        fmt.Println("Error: ", err)
        return
  }

  defer session.Close()

  session.SetMode(mgo.Monotonic, true)

  c := session.DB("test").C("people")

  var p = Person{
    Code: "1234",
    Name: "Bill",
  }
    upsertdata := bson.M{ "$set": p}

    info , err2 := c.UpsertId( p.Code, upsertdata )
    fmt.Println("UpsertId -> ", info, err2)
  result := Person{}
  err = c.FindId(p.Code).One(&result)
  if err != nil {
        fmt.Println("FindId Error: ", err)
        return
  }

  fmt.Println("Person", result)

}

非常感谢您对Neil的兴趣和帮助。

结构没有ID字段,这就是为什么UpsertId很方便的原因。但它并没有按照mgo文件所说的那样做。这就是为什么我最终会出现在mondogdb文档中。我希望Data.Code是_-id,但结构没有bson:“_-id”,因为它来自外部包。@GabrielDíaz我不知道你在问什么。您似乎希望提供一些不同的内容,如
\u id
。这就是这段代码的作用和工作原理。如果你的意思不同,那么也许你可以把你的问题说得更清楚。Upsert将使用给定的
\u id
值,除非有其他原因使其不能这样做。我已经用我正在做的编辑了您的示例。希望这有助于理解这个问题。谢谢@GabrielDíaz如果我理解你问题的语气,你是说upsert添加了它自己的
\u id
值。从我的清单和你的清单之间的差异来看,原因很清楚。查看结构上的映射。这是BSON序列化部分,这正是我所说的。我理解你的意思,但我的问题不同。阅读mgo驱动程序文档“如果没有找到与选择器匹配的文档,则更新文档将应用于选择器文档,并将结果插入集合”,我希望Upsert将提供的Id和提供的结构合并为对象,然后将其插入数据库。它不起作用,那么文档中“应用”的含义是什么?