COMPLEX SEARCH
This commit is contained in:
83
dbs/dbs.go
83
dbs/dbs.go
@@ -1,9 +1,92 @@
|
||||
package dbs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
type Operator int
|
||||
|
||||
const (
|
||||
LIKE Operator = iota
|
||||
EXISTS
|
||||
IN
|
||||
GTE
|
||||
LTE
|
||||
LT
|
||||
GT
|
||||
EQUAL
|
||||
)
|
||||
|
||||
var str = [...]string{
|
||||
"like",
|
||||
"exists",
|
||||
"in",
|
||||
"gte",
|
||||
"lte",
|
||||
"lt",
|
||||
"gt",
|
||||
"equal",
|
||||
}
|
||||
|
||||
func (m Operator) String() string {
|
||||
return str[m]
|
||||
}
|
||||
|
||||
func (m Operator) ToMongoOperator() string {
|
||||
switch m {
|
||||
case LIKE:
|
||||
return "$regex"
|
||||
case EXISTS:
|
||||
return "$exists"
|
||||
case IN:
|
||||
return "$in"
|
||||
case GTE:
|
||||
return "$gte"
|
||||
case GT:
|
||||
return "$gt"
|
||||
case LTE:
|
||||
return "$lte"
|
||||
case LT:
|
||||
return "$lt"
|
||||
case EQUAL:
|
||||
return "$match"
|
||||
default:
|
||||
return "$regex"
|
||||
}
|
||||
}
|
||||
|
||||
func StringToOperator(s string) Operator {
|
||||
for i, v := range str {
|
||||
if v == s {
|
||||
return Operator(i)
|
||||
}
|
||||
}
|
||||
return LIKE
|
||||
}
|
||||
|
||||
func ToValueOperator(operator Operator, value interface{}) interface{} {
|
||||
if strings.TrimSpace(fmt.Sprintf("%v", value)) == "*" {
|
||||
value = ""
|
||||
}
|
||||
if operator == LIKE {
|
||||
return "(?i).*" + strings.TrimSpace(fmt.Sprintf("%v", value)) + ".*"
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
type Filters struct {
|
||||
And map[string]Filter `json:"and"`
|
||||
Or map[string]Filter `json:"or"`
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Operator string `json:"operator,omitempty"`
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
type Input = map[string]interface{}
|
||||
|
||||
func InputToBson(i Input, isUpdate bool) bson.D {
|
||||
|
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||
@@ -261,27 +260,35 @@ func (m *MongoDB) LoadOne(id string, collection_name string) (*mongo.SingleResul
|
||||
return res, 200, nil
|
||||
}
|
||||
|
||||
func (m *MongoDB) Search(search string, filter []string, collection_name string) (*mongo.Cursor, int, error) {
|
||||
func (m *MongoDB) Search(filters dbs.Filters, collection_name string) (*mongo.Cursor, int, error) {
|
||||
if err := m.createClient(mngoConfig.GetUrl()); err != nil {
|
||||
return nil, 503, err
|
||||
}
|
||||
opts := options.Find()
|
||||
opts.SetLimit(100)
|
||||
if strings.TrimSpace(search) == "*" {
|
||||
search = ""
|
||||
}
|
||||
search = ".*" + strings.TrimSpace(search) + ".*"
|
||||
targetDBCollection := CollectionMap[collection_name]
|
||||
list := []bson.M{}
|
||||
for _, k := range filter {
|
||||
list = append(list, bson.M{k: bson.M{"$regex": search, "$options": "i"}})
|
||||
andList := []bson.E{}
|
||||
for k, filter := range filters.And {
|
||||
andList = append(andList, bson.E{Key: k, Value: bson.M{
|
||||
dbs.StringToOperator(filter.Operator).ToMongoOperator(): dbs.ToValueOperator(dbs.StringToOperator(filter.Operator), filter.Value)}})
|
||||
}
|
||||
orList := []bson.M{}
|
||||
for k, filter := range filters.Or {
|
||||
orList = append(orList, bson.M{
|
||||
k: bson.M{dbs.StringToOperator(filter.Operator).ToMongoOperator(): dbs.ToValueOperator(dbs.StringToOperator(filter.Operator), filter.Value)}})
|
||||
}
|
||||
MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
f := bson.D{}
|
||||
if len(andList) > 0 {
|
||||
f = append(f, andList...)
|
||||
}
|
||||
if len(orList) > 0 {
|
||||
f = append(f, bson.E{Key: "$or", Value: orList})
|
||||
}
|
||||
if cursor, err := targetDBCollection.Find(
|
||||
MngoCtx,
|
||||
bson.M{"$or": list},
|
||||
f,
|
||||
opts,
|
||||
); err != nil {
|
||||
return nil, 404, err
|
||||
@@ -327,24 +334,3 @@ func (m *MongoDB) LoadAll(collection_name string) (*mongo.Cursor, int, error) {
|
||||
}
|
||||
return res, 200, nil
|
||||
}
|
||||
|
||||
func (m *MongoDB) toOperator(operator string) string {
|
||||
if operator == "like" {
|
||||
return "$regex"
|
||||
} else if operator == "exists" {
|
||||
return "$exists"
|
||||
} else if operator == "in" {
|
||||
return "$in"
|
||||
} else if operator == "gte" {
|
||||
return "$gte"
|
||||
} else if operator == "gt" {
|
||||
return "$gt"
|
||||
} else if operator == "lte" {
|
||||
return "$lte"
|
||||
} else if operator == "lt" {
|
||||
return "$lt"
|
||||
} else if operator == "eq" {
|
||||
return "$match"
|
||||
}
|
||||
return operator
|
||||
}
|
||||
|
Reference in New Issue
Block a user