查询两个字段之和小于给定值
Query where sum of two fields is less than given value
我正在使用 Go 语言和 MongoDB 以及 mgo.v2
驱动程序并且我的结构类似于
type MarkModel struct {
ID bson.ObjectId `json: "_id,omitempty" bson: "_id,omitempty"`
Name string `json: "name" bson: "name"`
Sum int `json: "sum" bson: "sum"`
Delta int `json: "delta" bson: "delta"`
}
例如,我需要找到 Sum + Delta < 1000
所在的所有位置。目前我全部加载,然后在 Go 代码中进行过滤,但我想在查询级别进行过滤。
如何进行查询?
目前我return都和
marks := []MarkModel{}
c_marks := session.DB(database).C(marksCollection)
err := c_marks.Find(bson.M{}).All(&marks)
if err != nil {
panic(err)
}
这里我在 for 循环中过滤了 Go 代码,但它不是最优的(这是不好的解决方案)。
你真的应该为此使用 Aggregation Framework。然后它在服务器端处理。做类似的事情:
db.table.aggregate(
[
{ $project: { ID: 1, name : 1, total: { $add: [ "$Sum", "$Delta" ] } } },
{ $match : { total : { $gte: 1000 }}}
]
)
要查找 sum + delta < 1000
所在的所有位置,您可以使用:
pipe := c.Pipe(
[]bson.M{
bson.M{"$project": bson.M{"_id": 1, "name": 1, "sum": 1, "delta": 1,
"total": bson.M{"$add": []string{"$sum", "$delta"}}}},
bson.M{"$match": bson.M{"total": bson.M{"$lt": 1000}}},
})
这是工作代码:
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior.
c := session.DB("test").C("MarkModel")
c.DropCollection()
err = c.Insert(&MarkModel{bson.NewObjectId(), "n1", 10, 1}, &MarkModel{bson.NewObjectId(), "n2", 20, 2},
&MarkModel{bson.NewObjectId(), "n1", 100, 1}, &MarkModel{bson.NewObjectId(), "n2", 2000, 2})
if err != nil {
panic(err)
}
pipe := c.Pipe(
[]bson.M{
bson.M{"$project": bson.M{"_id": 1, "name": 1, "sum": 1, "delta": 1,
"total": bson.M{"$add": []string{"$sum", "$delta"}}}},
bson.M{"$match": bson.M{"total": bson.M{"$lt": 1000}}},
})
r := []bson.M{}
err = pipe.All(&r)
if err != nil {
panic(err)
}
for _, v := range r {
fmt.Println(v["_id"], v["sum"], v["delta"], v["total"])
}
fmt.Println()
}
type MarkModel struct {
ID bson.ObjectId `json: "_id,omitempty" bson: "_id,omitempty"`
Name string `json: "name" bson: "name"`
Sum int `json: "sum" bson: "sum"`
Delta int `json: "delta" bson: "delta"`
}
输出:
ObjectIdHex("57f62739c22b1060591c625f") 10 1 11
ObjectIdHex("57f62739c22b1060591c6260") 20 2 22
ObjectIdHex("57f62739c22b1060591c6261") 100 1 101
我正在使用 Go 语言和 MongoDB 以及 mgo.v2
驱动程序并且我的结构类似于
type MarkModel struct {
ID bson.ObjectId `json: "_id,omitempty" bson: "_id,omitempty"`
Name string `json: "name" bson: "name"`
Sum int `json: "sum" bson: "sum"`
Delta int `json: "delta" bson: "delta"`
}
例如,我需要找到 Sum + Delta < 1000
所在的所有位置。目前我全部加载,然后在 Go 代码中进行过滤,但我想在查询级别进行过滤。
如何进行查询?
目前我return都和
marks := []MarkModel{}
c_marks := session.DB(database).C(marksCollection)
err := c_marks.Find(bson.M{}).All(&marks)
if err != nil {
panic(err)
}
这里我在 for 循环中过滤了 Go 代码,但它不是最优的(这是不好的解决方案)。
你真的应该为此使用 Aggregation Framework。然后它在服务器端处理。做类似的事情:
db.table.aggregate(
[
{ $project: { ID: 1, name : 1, total: { $add: [ "$Sum", "$Delta" ] } } },
{ $match : { total : { $gte: 1000 }}}
]
)
要查找 sum + delta < 1000
所在的所有位置,您可以使用:
pipe := c.Pipe(
[]bson.M{
bson.M{"$project": bson.M{"_id": 1, "name": 1, "sum": 1, "delta": 1,
"total": bson.M{"$add": []string{"$sum", "$delta"}}}},
bson.M{"$match": bson.M{"total": bson.M{"$lt": 1000}}},
})
这是工作代码:
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true) // Optional. Switch the session to a monotonic behavior.
c := session.DB("test").C("MarkModel")
c.DropCollection()
err = c.Insert(&MarkModel{bson.NewObjectId(), "n1", 10, 1}, &MarkModel{bson.NewObjectId(), "n2", 20, 2},
&MarkModel{bson.NewObjectId(), "n1", 100, 1}, &MarkModel{bson.NewObjectId(), "n2", 2000, 2})
if err != nil {
panic(err)
}
pipe := c.Pipe(
[]bson.M{
bson.M{"$project": bson.M{"_id": 1, "name": 1, "sum": 1, "delta": 1,
"total": bson.M{"$add": []string{"$sum", "$delta"}}}},
bson.M{"$match": bson.M{"total": bson.M{"$lt": 1000}}},
})
r := []bson.M{}
err = pipe.All(&r)
if err != nil {
panic(err)
}
for _, v := range r {
fmt.Println(v["_id"], v["sum"], v["delta"], v["total"])
}
fmt.Println()
}
type MarkModel struct {
ID bson.ObjectId `json: "_id,omitempty" bson: "_id,omitempty"`
Name string `json: "name" bson: "name"`
Sum int `json: "sum" bson: "sum"`
Delta int `json: "delta" bson: "delta"`
}
输出:
ObjectIdHex("57f62739c22b1060591c625f") 10 1 11
ObjectIdHex("57f62739c22b1060591c6260") 20 2 22
ObjectIdHex("57f62739c22b1060591c6261") 100 1 101