RethinkDB 上具有 OR 条件的两个过滤器
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
}
我怎样才能使它以更简单的方式工作?
我将在这里召集@daniel-cannon,但我认为这就是您正在寻找的,并且会极大地简化此查询并将其减少为单个查询。但只有两个提示:
r.And
和 r.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)
希望对您有所帮助!
我有一个结构:
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
}
我怎样才能使它以更简单的方式工作?
我将在这里召集@daniel-cannon,但我认为这就是您正在寻找的,并且会极大地简化此查询并将其减少为单个查询。但只有两个提示:
r.And
和r.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)
希望对您有所帮助!