Sending a MongoDB query to a different system: converting to JSON and then decoding into BSON? How to do it in Go language?

huangapple go评论80阅读模式
英文:

Sending a MongoDB query to a different system: converting to JSON and then decoding into BSON? How to do it in Go language?

问题

我需要将一个 MongoDB 查询转换到另一个系统中。出于这个原因,我想使用MongoDB Extended JSON。我之所以需要这样做,主要是因为我在查询中使用了日期比较。

所以,问题的关键是我需要将在 node.js 后端生成的 MongoDB 查询转移到另一个使用 Go 语言编写的后端。

直观上,通过 REST 发送这个查询的最明显的格式是 JSON。但是,MongoDB 查询并不完全是 JSON,而是 BSON,其中包含了日期的特殊结构。

因此,想法是使用MongoDB Extended JSON将查询转换为 JSON,作为特殊结构的表示形式。经过一些测试,明显这些查询是不起作用的。MongoDB shell 和通过 node.js 发送的查询都需要特殊的 ISODatenew Date 结构。

最后,实际的问题是:在 JavaScript(node.js)和 Go 语言中,是否有编码/解码 JSON 到 BSON 的函数,考虑到MongoDB Extended JSON

更新

Node.js 编码包

显然,有一个 node.js可以解析和字符串化 BSON/JSON。所以,我的问题的一半已经解决了。我想知道 Go 语言中是否有类似的东西。

示例查询

例如,以下查询是普通 BSON 格式的:

{ Tmin: { $gt: ISODate("2006-01-01T23:00:00.000Z") } }

转换为 MongoDB Extended JSON 后,变成了:

{ "Tmin": { "$gt" : { "$date" : 1136156400000 }}}
英文:

I need to transfer a MongoDB query to a different system. For this reason I would like to use the MongoDB Extended JSON. I need this to be done mostly because I use date comparisons in my queries.

So, the kernel of the problem is that I need to transfer a MongoDB query that has been generated in a node.js back-end to another back-end written in Go language.

Intuitively, the most obvious format for sending this query via REST, is JSON. But, MongoDB queries are not exactly JSON, but BSON, which contains special constructs for dates.

So, the idea is to convert the queries into JSON using MongoDB Extended JSON as form of representation of the special constructs. After some tests it's clear that these queries do not work. Both the MongoDB shell and queries sent via node.js's need the special ISODate or new Date constructs.

Finally, the actual question: are there functions to encode/decode from JSON to BSON, taking into account MongoDB Extended JSON, both in JavaScript (node.js) and Go language?

Updates

Node.js encoding package

Apparently there is a node.js package that parses and stringifies BSON/JSON.
So, half of my problem is resolved. I wonder if there is something like this in Go language.

Sample query

For example, the following query is in normal BSON:

{ Tmin: { $gt: ISODate("2006-01-01T23:00:00.000Z") } }

Translated into MongoDB Extended JSON, it becomes:

{ "Tmin": { "$gt" : { "$date" : 1136156400000 }}}

答案1

得分: 4

经过一些研究,我找到了mejson库,但它只用于编组,所以我决定编写一个解组器。

请看ejson(我编写的),目前它是一个非常简单的ejsonbson转换器,还没有bsonejson的转换器,你可以使用mejson来实现。

以下是一个示例

const j = `{"_id":{"$oid":"53c2ab5e4291b17b666d742a"},"last_seen_at":{"$date":1405266782008},"display_name":{"$undefined":true},
"ref":{"$ref":"col2", "$id":"53c2ab5e4291b17b666d742b"}}`

type TestS struct {
    Id          bson.ObjectId `bson:"_id"`
    LastSeenAt  *time.Time    `bson:"last_seen_at"`
    DisplayName *string       `bson:"display_name,omitempty"`
    Ref         mgo.DBRef     `bson:"ref"`
}

func main() {
    var ts TestS
    if err := ejson.Unmarshal([]byte(j), &ts); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", ts)

    //or to convert the ejson to bson.M

    var m map[string]interface{}
    if err := json.Unmarshal([]byte(j), &m); err != nil {
        t.Fatal(err)
    }
    err := ejson.Normalize(m)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", m)
}

希望对你有帮助!

英文:

After some research I found the mejson library, however it's for Marshaling only, so I decided to write an Unmarshaller.

Behold ejson (I wrote it), right now it's a very simple ejson -> bson converter, there's no bson -> ejson yet, you can use mejson for that.

An example:

const j = `{"_id":{"$oid":"53c2ab5e4291b17b666d742a"},"last_seen_at":{"$date":1405266782008},"display_name":{"$undefined":true},
"ref":{"$ref":"col2", "$id":"53c2ab5e4291b17b666d742b"}}`

type TestS struct {
	Id          bson.ObjectId `bson:"_id"`
	LastSeenAt  *time.Time    `bson:"last_seen_at"`
	DisplayName *string       `bson:"display_name,omitempty"`
	Ref         mgo.DBRef     `bson:"ref"`
}

func main() {
	var ts TestS
	if err := ejson.Unmarshal([]byte(j), &ts); err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", ts)

	//or to convert the ejson to bson.M

	var m map[string]interface{}
	if err := json.Unmarshal([]byte(j), &m); err != nil {
		t.Fatal(err)
	}
	err := ejson.Normalize(m)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", m)

}

huangapple
  • 本文由 发表于 2014年8月9日 19:26:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/25218061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定