【问题标题】:How to run a query with Boolean property check如何使用布尔属性检查运行查询
【发布时间】:2019-11-15 08:28:29
【问题描述】:

文件夹文档:

{"_id":"5d1e2da512ad38225af60869","id":1,"name":"inbox","must":true}
{"_id":"5d1e2da512ad38225af6086b","id":2,"name":"outbox","must":true}
{"_id":"5d1e2da512ad38225af6086d","id":3,"name":"drafts","must":true}
{"_id":"5d1e2da512ad38225af6086f","id":4,"name":"trash","must":true}

邮件文件:

{"_id":"5d1e2da512ad38225af60871","id":1,"isdeleted":true,"foldersids":[1],"subject":"Hello1","body":"Hello this is mail 1"}
{"_id":"5d1e2da512ad38225af60873","id":2,"isdeleted":false,"foldersids":[1],"subject":"Hello2","body":"Hello this is mail 2"}

我正在尝试获取所有未标记为已删除的邮件,并仅获取其 Id 值,这是一个单独的字段(不是 object_id 字段)

在我的数据库中,我有 2 个文档 - 1 个标记为已删除,1 个标记为未删除。此代码始终返回两个文档,尽管预期结果是它仅返回未删除的文档的 Id。什么可能导致它失败?

编辑:完整示例

我的 golang 代码

Folder.go

package main

type Folder struct {
    Id int
    Name string
    Must bool
}

Mail.go

package main

type Mail struct{
    Id int
    IsDeleted bool
    FoldersIds []int
    Subject string
    Body string
}

ma​​in.go

package main

import (
    "fmt"
    "github.com/globalsign/mgo"
    "github.com/globalsign/mgo/bson"
)

func main(){
    inbox := Folder{
        Id:1,
        Name:"inbox",
        Must:true,
    }
    outbox := Folder{
        Id:2,
        Name:"outbox",
        Must:true,
    }
    drafts := Folder{
        Id:3,
        Name:"drafts",
        Must:true,
    }
    trash := Folder{
        Id:4,
        Name:"trash",
        Must:true,
    }

    session, _ := mgo.Dial("localhost:27017")

    session.DB("Outlook").C("Folders").Upsert(bson.M{"id": inbox.Id}, inbox)
    session.DB("Outlook").C("Folders").Upsert(bson.M{"id": outbox.Id}, outbox)
    session.DB("Outlook").C("Folders").Upsert(bson.M{"id": drafts.Id}, drafts)
    session.DB("Outlook").C("Folders").Upsert(bson.M{"id": trash.Id}, trash)

    mail1 := Mail{Id:1,Body:"Hello this is mail 1", FoldersIds:[]int{1}, IsDeleted:true, Subject:"Hello1"}
    mail2 := Mail{Id:2,Body:"Hello this is mail 2", FoldersIds:[]int{1}, IsDeleted:false, Subject:"Hello2"}

    session.DB("Outlook").C("Mails").Upsert(bson.M{"id": 1}, mail1)
    session.DB("Outlook").C("Mails").Upsert(bson.M{"id": 2}, mail2)

    var mails []Mail

    session.DB("Outlook").C("Mails").Find(bson.M{"IsDeleted": bson.M{"$ne": true}}).Select(bson.M{"Id": 1}).All(&mails)

    fmt.Println(len(mails)) // Why is this 2 and not 1?????
}

【问题讨论】:

  • 请在 MongoDB 中发布您的文档。 db.mails.find()的输出。
  • @icza 我在这里做了一个简单的例子,希望它包含所有需要的细节

标签: database mongodb go mgo


【解决方案1】:

MongoDB 文档字段的名称区分大小写。您在数据库中的文档具有小写的字段名称,例如isdeletedid。所以你在构造你的过滤器的时候也必须这样写:

session.DB("Outlook").C("Mails").Find(bson.M{
    "isdeleted": bson.M{"$ne": true},
}).Select(bson.M{"id": 1}).All(&mails)

如果您想更改名称在数据库中的保存方式,请使用bson struct tag,例如:

type Mail struct {
    Id         int    `bson:"Id"`
    IsDeleted  bool   `bson:"IsDeleted"`
    FoldersIds []int  `bson:"FolderIds"`
    Subject    string `bson:"Subject"`
    Body       string `bson:"Body"`
}

通常Camel case 用于由多个单词组成的名称:

type Mail struct {
    Id         int    `bson:"id"`
    IsDeleted  bool   `bson:"isDeleted"`
    FoldersIds []int  `bson:"folderIDs"`
    Subject    string `bson:"subject"`
    Body       string `bson:"body"`
}

但你可以使用任何命名策略,一切都会奏效,但要保持一致。

【讨论】:

    猜你喜欢
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 2023-03-29
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多