英文:
Two filters with an OR-condition on RethinkDB
问题
我有一个结构体:
type Talk struct {
Id string `gorethink:"id,omitempty"`
MatchId string
UserIdX string
UserIdY string
UserNameX string
UserNameY string
CreatedAt time.Time
}
我的当前Talk
结构体如下所示:
{
"CreatedAt": "Wed Sep 14 2016 21:36:26 GMT+02:00",
"MatchId": "172d51fa-438b-49a5-bbe5-422377f09336",
"UserIdX": "acc4e0b6-d33b-4755-9c0a-ae5309c2ba75",
"UserIdY": "03f76d8b-ed6a-4c0f-9cde-27b17c9e7cdb",
"UserNameX": "Barbara",
"UserNameY": "Louis",
"id": "ead3f1b0-b242-4c6d-8027-a59572b58649"
}
如何使用单个查询检索对话,其中:
(UserIdX == talk.UserIdX AND UserIdY == talk.UserIdY) OR (UserIdX == talk.UserIdY AND UserIdY == talk.UserIdX)
我目前是这样做的:
func (talk *Talk) GetTalkByUsersId() bool {
talk1 := new(Talk)
talk2 := new(Talk)
curs, _ := r.Table("Talks").
Filter(r.Row.Field("UserIdX").Eq(talk.UserIdX)).
Filter(r.Row.Field("UserIdY").Eq(talk.UserIdY)).
Run(api.Sess)
curs2, _ := r.Table("Talks").
Filter(r.Row.Field("UserIdX").Eq(talk.UserIdY)).
Filter(r.Row.Field("UserIdY").Eq(talk.UserIdX)).
Run(api.Sess)
curs.One(&talk1)
curs2.One(&talk2)
if talk1.Id == "" && talk2.Id == "" {
return false
}
if talk1.Id != "" {
talk.copyTalk(talk1)
} else {
talk.copyTalk(talk2)
}
return true
}
如何以更简单的方式实现这个功能?
英文:
I've a struct :
type Talk struct {
Id string `gorethink:"id,omitempty"`
MatchId string
UserIdX string
UserIdY string
UserNameX string
UserNameY string
CreatedAt time.Time
}
My current Talk
struct looks like this:
{
"CreatedAt": Wed Sep 14 2016 21:36:26 GMT+02:00 ,
"MatchId": "172d51fa-438b-49a5-bbe5-422377f09336" ,
"UserIdX": "acc4e0b6-d33b-4755-9c0a-ae5309c2ba75" ,
"UserIdY": "03f76d8b-ed6a-4c0f-9cde-27b17c9e7cdb" ,
"UserNameX": "Barbara" ,
"UserNameY": "Louis" ,
"id": "ead3f1b0-b242-4c6d-8027-a59572b58649"
}
How can I retrieve a talk, with a single query, where:
> (UserIdX == talk.UserIdX AND UserIdY == talk.UserIdY) OR (UserIdX ==
> talk.UserIdY AND UserIdY == talk.UserIdX)
I actually do it like the following:
func (talk *Talk) GetTalkByUsersId() bool {
talk1 := new(Talk)
talk2 := new(Talk)
curs, _ := r.Table("Talks").
Filter(r.Row.Field("UserIdX").Eq(talk.UserIdX)).
Filter(r.Row.Field("UserIdY").Eq(talk.UserIdY)).
Run(api.Sess)
curs2, _ := r.Table("Talks").
Filter(r.Row.Field("UserIdX").Eq(talk.UserIdY)).
Filter(r.Row.Field("UserIdY").Eq(talk.UserIdX)).
Run(api.Sess)
curs.One(&talk1)
curs2.One(&talk2)
if talk1.Id == "" && talk2.Id == "" {
return false
}
if talk1.Id != "" {
talk.copyTalk(talk1)
} else {
talk.copyTalk(talk2)
}
return true
}
How can I get this to work in a much simpler way?
答案1
得分: 2
我将在这里召唤 @daniel-cannon,但我认为这就是你要找的,并且将大大简化这个查询并将其减少为一个查询。但是有两个提示:
r.And
和r.Or
及其两种用法非常适合处理一些棘手的逻辑条件。- https://www.rethinkdb.com/api/javascript/#and
- https://www.rethinkdb.com/api/javascript/#or
- 你可以向
.Filter
提供匿名函数来执行使用简化的r.Row
模式可能会有些丑陋的操作。
r.Table("talks").Filter(func(talk r.Term) r.Term {
return r.Or(
r.And(talk.Field("UserIdX").Eq(UserIdX), talk.Field("UserIdX").Eq(UserIdY)),
r.And(talk.Field("UserIdY").Eq(UserIdX), talk.Field("UserIdX").Eq(UserIdY)),
)
}).Run(api.Sess)
希望这可以帮到你!
英文:
I'm going to summon @daniel-cannon here but I think this is what you're looking for and will vastly simplify this query and reduce it to just a single query. But just two tips:
r.And
andr.Or
and their two use cases are very much your friends for doing some tricky logical conditions.- https://www.rethinkdb.com/api/javascript/#and
- https://www.rethinkdb.com/api/javascript/#or
- You can provide anonymous functions to
.Filter
to do things that would be kind of ugly with the simplifiedr.Row
pattern.
<!-- language: lang-golang -->
r.Table("talks").Filter(func(talk r.Term) r.Term {
return r.Or(
r.And(talk.Field("UserIdX").Eq(UserIdX), talk.Field("UserIdX").Eq(UserIdY)),
r.And(talk.Field("UserIdY").Eq(UserIdX), talk.Field("UserIdX").Eq(UserIdY)),
)
}).Run(api.Sess)
I hope this helps!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论