英文:
MongoDB find query with combination of $or and $and in golang
问题
我想获取满足以下条件的行:
{修理字段包含“ac”或{修理为“tv”且电话字段在1091-1100范围内}}
我正在尝试以下查询:
type M map[string]interface{}
conditions := M{"name": M{"$regex": "me"},
"$or": []M{M{"repair": M{"$eq": "ac"}},
"$and": []M{M{"repair": M{"$eq": "tv"}}, M{"phone": M{"$gte": 1091, "$lte": 1100}}}}}
fmt.Println(conditions)
err = c.Find(conditions).Sort("phone").Limit(20).All(&j)
然而,我得到了一个编译错误:
索引必须是非负整数常量
无法将[]M字面量(类型[]M)用作数组或切片字面量中的M类型。
英文:
I want to get rows where:
{repair field has "ac" OR {repair is "tv" and phone field in range 1091-1100}}
I am trying the following query:
type M map[string]interface{}
conditions := M{"name": M{"$regex": "me"},
"$or": []M{M{"repair": M{"$eq": "ac"}},
"$and": []M{M{"repair": M{"$eq": "tv"}}, M{"phone": M{"$gte": 1091, "$lte": 1100}}}}}
fmt.Println(conditions)
err = c.Find(conditions).Sort("phone").Limit(20).All(&j)
However, I am getting a compile error:
index must be non-negative integer constant
cannot use []M literal (type []M) as type M in array or slice literal.
答案1
得分: 1
你在"$and"
之前缺少一个M{
,在添加这个之后,不要忘记再添加一个闭合大括号}
。
英文:
You're missing one M{
before "$and"
and after you add that don't forget to add another closing brace }
.
答案2
得分: 0
我不知道你在使用哪个驱动程序,但我可能会这样做:
package main
import (
"log"
"time"
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
const (
databaseString = ""
)
var db DataStore
type DataStore struct {
Session *mgo.Session
}
// 连接数据库
func (ds *DataStore) ConnectToDB() {
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{"localhost:27017"},
Timeout: 1 * time.Hour,
}
sess, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
sess.Refresh()
panic(err)
}
sess.SetMode(mgo.Monotonic, true)
db.Session = sess
}
// J 是预期的 MongoDB 返回对象
type J struct {
ID bson.ObjectId `bson:"_id,omitempty" json:"_id"`
Status string `bson:"status" json:"status"`
}
func init() {
db.ConnectToDB()
}
func main() {
colectionString := ""
var j J
conditions := bson.M{
"name": bson.M{"$regex": "me"},
"$or": []bson.M{
bson.M{"repair": bson.M{"$eq": "ac"}},
},
"$and": []bson.M{
bson.M{"repair": bson.M{"$eq": "tv"}},
bson.M{"phone": bson.M{"$gte": 1091, "$lte": 1100}},
},
}
err := db.Session.DB(databaseString).C(colectionString).Find(conditions).Sort("phone").Limit(20).All(&j)
if err != nil {
log.Fatal(err)
}
}
我可能还会创建一个单独的包来处理 MongoDB 连接,这样我可以在调用周围编写包装函数:
func FindItem(sess *mgo.Session, id string) (data, error) {
defer sess.Close()
var res data // 一些数据类型的结构体
err := sess.DB("my db").C("my collection").Find(bson.M{"user": someID}).One(&data)
return data, err
}
然后我可以这样做,以支持并发:
res, err := packagemain.FindItem(sess.Copy(), someID)
在你的原始代码中,你缺少了 }
和 ,
。我建议你使用 go vet
或一个可以为你检查代码的 IDE。另外,如果你还没有使用 mgo
,那么你可能需要使用它作为 MongoDB 驱动程序。
英文:
I don't know what driver your using, but I would probably do something like this..
package main
import (
"log"
"time"
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
const (
databaseString = ""
)
var db DataStore
type DataStore struct {
Session *mgo.Session
}
// database
func (ds *DataStore) ConnectToDB() {
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{"localhost:27017"},
Timeout: 1 * time.Hour,
}
sess, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
sess.Refresh()
panic(err)
}
sess.SetMode(mgo.Monotonic, true)
db.Session = sess
}
// J is the expected mongo return object
type J struct {
ID bson.ObjectId `bson:"_id,omitempty" json:"_id"`
// example data below
Status string `bson:"status" json:"status"`
}
func init() {
db.ConnectToDB()
}
func main() {
colectionString := ""
// probably best if this was a mapped mgo struct see above
// var j bson.M
var j J
// your orignal code
// I don't know why you are using $eq couldn't you just do bson.M{"repair":"ac"}, and bson.M{"repair":"tv"}
conditions := bson.M{"name": bson.M{"$regex": "me"},
"$or": []bson.M{
bson.M{"repair": bson.M{"$eq": "ac"}},
},
"$and": []bson.M{
bson.M{"repair": bson.M{"$eq": "tv"}},
bson.M{"phone": bson.M{"$gte": 1091, "$lte": 1100}},
}}
err := db.Session.DB(databaseString).C(colectionString).Find(conditions).Sort("phone").Limit(20).All(&j)
if err != nil {
log.Fatal(err)
}
}
I would probably also end up creating a separate package for the mongo connection stuff so that I can write wrapper functions around calls,
func FindItem(db *mgo.Session, id string) (data, error) {
defer sess.Close()
var res data //some data type struct
err := sess.DB("my db").C("my collection").Find(bson.M{"user": someID}).One(&data)
return data, err
}
then I'd be able to do things like this, which allow for concurrency
res, err := packagemain.FindItem(sess.Copy(), someID)
and your original code your you where missing }
and ,
. I suggest you use go vet
or an ide which vets the code for you. Also, mgo
is the mongo driver you probably what you want to be using if you're not using it already.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论