猿问

Golang 中的 Firestore 动态复合查询

我正在构建一个集合API,它将返回firestore的文档集合列表,其中可以发送动态查询,如下所示GETClient side


type Condition struct {

  Field    string

  Operator string

  Value    interface{}

}


// Client side 

conditions := []*Condition{

    {Field: "email", Operator: "==", Value:"some@email"},

    {Field: "fullname", Operator: "==", Value: "somename"},

}


docs := Get("user", conditions)

// do something with docs    



// Server side

func Get(cn string, conditions []*Condition) *firestore.DocumentIterator {

  collection := firestoreClient.Collection(cn)


  for _, v := range conditions {

    collection.Where(v.Field, v.Operator, v.Value)

  }


  return collection.Documents(ctx)

}

这返回没有错误,但是它不是返回具有匹配条件的文档,而是只返回集合中的所有内容,当然我可以像这样做


....

cn := "user"

collection := client.Collection(cn)

collection.

  Where("email", "==", "some@email").

  Where("fullname", "==", "somename").

  //chain some other Where condition

我已经在任何地方搜索过,但提供的解决方案是通过手动链接如上所述的方法,这并不理想,因为将控制查询。我不想为每个可能的查询组合创建一个函数,我也不认为这是最好的方法。WhereClient side


如何在Golang Firestore中实现这一点?


更新


接受的答案正在工作,但是它不会检查客户端是否没有发送任何内容,它将触发.所以我添加了一些检查,以防万一有人偶然发现同样的问题where conditionsnull pointer error


type FirestoreConditions struct {

    Field    string

    Operator string

    Value    interface{}

}


// conditions []*FirestoreConditions


var q firestore.Query

if len(conditions) > 0 {

    for i, v := range conditions {

        if i == 0 {

            q = collection.Where(v.Field, v.Operator, v.Value)

            continue

        }

        q = q.Where(v.Field, v.Operator, v.Value)

    }

    q = q.OrderBy(query.OrderBy, sort).Limit(int(query.Limit)).Offset(int(query.Offset))

} else {

    q = collection.OrderBy(query.OrderBy, sort).Limit(int(query.Limit)).Offset(int(query.Offset))

}


弑天下
浏览 93回答 2
2回答

呼啦一阵风

您需要定义返回值的变量类型。从集合中为数组中的第一个数据创建查询,然后为下一个数据追加查询var q firestore.Queryfor i, v := range conditions {    if i == 0 {        q = collection.Where(v.Field, v.Operator, v.Value)    } else {        q = q.Where(v.Field, v.Operator, v.Value)    }}通过引用该查询获取结果iter := q.Documents(ctx)

开心每一天1111

将循环修改为此for _, v := range conditions {     collection = collection.Where(v.Field, v.Operator, v.Value) }
随时随地看视频慕课网APP

相关分类

Go
我要回答