gorethink 内连接
gorethink inner join
我不放弃理解 RethinkDB 中的连接,不幸的是,关于它的德语文档很少。
所以我有一个 table 'categories' 并且我有两个文档:
{"id":1, "title":"Category 1"}
{"id":2, "title":"Category 2"}
我有第二个 table 'forums' 并且我有三个文档:
{"id":1, "title":"Forum 1", "categoryId":1}
{"id":2, "title":"Forum 2", "categoryId":1}
{"id":3, "title":"Forum 3", "categoryId":2}
我想要的结果是:
[{"id":1, "title":"Category 1", "forums":[{"id":1, "title":"Forum 1"},{"id":2, "title":"Forum 2"}]}, {"id":2, "title":"Category 2", "forums":[{"id":3, "title":"Forum 3"}]}]
我不知道如何将这个 JavaScript 示例 (https://www.rethinkdb.com/api/javascript/#inner_join) 转换为 Go,因为函数中的参数 (marvelRow, dcRow) 需要在 Go 中声明,但我不知道哪个。
我们先用JavaScript写,然后用Go来写,下次你就知道怎么写了。
您想要的可以通过连接或映射轻松实现。但是,join 会 return 一对匹配文档,而不是按照你想要的嵌套方式。然而,我们可以这样映射它:
r.table('categories')
.merge(function(cat) {
return {
forums: r.table('forums').filter({categoryId: cat('id')}).without('categoryId').coerceTo('array')
}
})
现在让我们转到 Go 语言。
package main
import (
r "github.com/dancannon/gorethink"
"log"
)
func main() {
s, _ := r.Connect(r.ConnectOpts{
Address: "127.0.0.1:28015",
Database: "test",
MaxIdle: 10,
MaxOpen: 10,
})
res, err := r.DB("test").Table("categories").Merge(func(doc r.Term) interface{} {
return map[string]interface{}{
"forums": r.DB("test").Table("forums").Filter(map[string]interface{}{
"categoryId": doc.Field("id"),
}).CoerceTo("array"),
}
}).Run(s)
log.Println(err)
var row interface{}
for res.Next(&row) {
log.Println(row)
}
}
一切都几乎相同,除了在 Go 语言中,您必须指定类型。因此,您将 JS 匿名函数转换为 Go lang 匿名函数,但现在大多数情况下所有内容的类型都是 r.Term
。您还必须指定 return 类型,因为我们在本例中使用 interface
。 JavaScript 对象现在变为 map[string]interface{}
。
一般来说,只需转到此页面 https://github.com/dancannon/gorethink/wiki/Go-ReQL-command-reference 并开始一步一步地转换 JS。除了类型,几乎是一对一的映射。
SQL 将是:
select c.id 作为 cId,
f.id 作为 fid
来自类别 c
在 f.categoryId = c.id
上加入论坛 f
注意:您可以添加两个表中的其他列。
我不放弃理解 RethinkDB 中的连接,不幸的是,关于它的德语文档很少。
所以我有一个 table 'categories' 并且我有两个文档:
{"id":1, "title":"Category 1"}
{"id":2, "title":"Category 2"}
我有第二个 table 'forums' 并且我有三个文档:
{"id":1, "title":"Forum 1", "categoryId":1}
{"id":2, "title":"Forum 2", "categoryId":1}
{"id":3, "title":"Forum 3", "categoryId":2}
我想要的结果是:
[{"id":1, "title":"Category 1", "forums":[{"id":1, "title":"Forum 1"},{"id":2, "title":"Forum 2"}]}, {"id":2, "title":"Category 2", "forums":[{"id":3, "title":"Forum 3"}]}]
我不知道如何将这个 JavaScript 示例 (https://www.rethinkdb.com/api/javascript/#inner_join) 转换为 Go,因为函数中的参数 (marvelRow, dcRow) 需要在 Go 中声明,但我不知道哪个。
我们先用JavaScript写,然后用Go来写,下次你就知道怎么写了。
您想要的可以通过连接或映射轻松实现。但是,join 会 return 一对匹配文档,而不是按照你想要的嵌套方式。然而,我们可以这样映射它:
r.table('categories')
.merge(function(cat) {
return {
forums: r.table('forums').filter({categoryId: cat('id')}).without('categoryId').coerceTo('array')
}
})
现在让我们转到 Go 语言。
package main
import (
r "github.com/dancannon/gorethink"
"log"
)
func main() {
s, _ := r.Connect(r.ConnectOpts{
Address: "127.0.0.1:28015",
Database: "test",
MaxIdle: 10,
MaxOpen: 10,
})
res, err := r.DB("test").Table("categories").Merge(func(doc r.Term) interface{} {
return map[string]interface{}{
"forums": r.DB("test").Table("forums").Filter(map[string]interface{}{
"categoryId": doc.Field("id"),
}).CoerceTo("array"),
}
}).Run(s)
log.Println(err)
var row interface{}
for res.Next(&row) {
log.Println(row)
}
}
一切都几乎相同,除了在 Go 语言中,您必须指定类型。因此,您将 JS 匿名函数转换为 Go lang 匿名函数,但现在大多数情况下所有内容的类型都是 r.Term
。您还必须指定 return 类型,因为我们在本例中使用 interface
。 JavaScript 对象现在变为 map[string]interface{}
。
一般来说,只需转到此页面 https://github.com/dancannon/gorethink/wiki/Go-ReQL-command-reference 并开始一步一步地转换 JS。除了类型,几乎是一对一的映射。
SQL 将是:
select c.id 作为 cId, f.id 作为 fid 来自类别 c 在 f.categoryId = c.id
上加入论坛 f注意:您可以添加两个表中的其他列。