Skip to content

Commit

Permalink
add 'distinct' option to node query to return list of distinct values…
Browse files Browse the repository at this point in the history
…. must be for an indexed field in node.attributes
  • Loading branch information
teharrison committed May 19, 2016
1 parent a46d6f3 commit f1dc25c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
21 changes: 19 additions & 2 deletions shock-server/controller/node/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (cr *NodeController) ReadMany(ctx context.Context) error {

// Gather params to make db query. Do not include the following list.
if _, ok := query["query"]; ok {
paramlist := map[string]int{"query": 1, "limit": 1, "offset": 1, "order": 1, "direction": 1}
paramlist := map[string]int{"query": 1, "limit": 1, "offset": 1, "order": 1, "direction": 1, "distinct": 1}
for key := range query {
if _, found := paramlist[key]; !found {
keyStr := fmt.Sprintf("attributes.%s", key)
Expand All @@ -86,7 +86,7 @@ func (cr *NodeController) ReadMany(ctx context.Context) error {
}
}
} else if _, ok := query["querynode"]; ok {
paramlist := map[string]int{"querynode": 1, "limit": 1, "offset": 1, "order": 1, "direction": 1, "owner": 1, "read": 1, "write": 1, "delete": 1, "public_owner": 1, "public_read": 1, "public_write": 1, "public_delete": 1}
paramlist := map[string]int{"querynode": 1, "limit": 1, "offset": 1, "order": 1, "direction": 1, "distinct": 1, "owner": 1, "read": 1, "write": 1, "delete": 1, "public_owner": 1, "public_read": 1, "public_write": 1, "public_delete": 1}
for key := range query {
if _, found := paramlist[key]; !found {
for _, value := range query[key] {
Expand Down Expand Up @@ -144,6 +144,23 @@ func (cr *NodeController) ReadMany(ctx context.Context) error {
// Combine permissions query with query parameters and ACL query into one AND clause
q["$and"] = []bson.M{qPerm, qOpts, qAcls}

// process distinct query
if _, ok := query["distinct"]; ok {
dField := query.Get("distinct")
if !node.HasAttributeField(dField) {
err_msg := "err unable to run distinct query on non-indexed attributes field: " + dField
logger.Error(err_msg)
return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
}
results, err := node.DbFindDistinct(q, dField)
if err != nil {
err_msg := "err " + err.Error()
logger.Error(err_msg)
return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
}
return responder.RespondWithData(ctx, results)
}

// defaults
order := "created_on"
direction := "-"
Expand Down
17 changes: 17 additions & 0 deletions shock-server/node/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ func Initialize() {
}
}

func HasAttributeField(a string) bool {
for _, b := range strings.Split(conf.MONGODB_ATTRIBUTE_INDEXES, ",") {
if a == strings.TrimSpace(b) {
return true
}
}
return false
}

func dbDelete(q bson.M) (err error) {
session := db.Connection.Session.Copy()
defer session.Close()
Expand Down Expand Up @@ -77,6 +86,14 @@ func dbFind(q bson.M, results *Nodes, order string, options map[string]int) (cou
return
}

func DbFindDistinct(q bson.M, d string) (results interface{}, err error) {
session := db.Connection.Session.Copy()
defer session.Close()
c := session.DB(conf.MONGODB_DATABASE).C("Nodes")
err = c.Find(q).Distinct("attributes."+d, &results)
return
}

func Load(id string) (n *Node, err error) {
session := db.Connection.Session.Copy()
defer session.Close()
Expand Down

0 comments on commit f1dc25c

Please sign in to comment.