1

We have an aggregation query in RestHeart which works well.

In the match section, we allow users to specify a specific document Id, to return just that document:

                "_$match" : {
                    "_id" : {
                        "_$var" : "n"
                    },

However, we've also like users to be able to omit this, and get all documents in the collection.

Is there any way to make avars optional, or to specify a wildcard for that avar? Currently if the user omits the avar, they get an error. And setting the avar to null or an empty string literally matches those values.

I guess another alternative would be if there can be conditional logic in the aggregation query properties -- not sure if this is possible.

Thanks

Tom

Tom Kerswill
  • 421
  • 6
  • 10

2 Answers2

1

I have found a simpler solution. The aggregation query in the _properties collection can be kept as-is, but instead, a wildcard can be specified in the GET request. Here is an example:

GET https://test.restheartapi.com:4443/DataBase/collection/_aggrs/items?avars={"n":/.*/, "m":/.*/ }

... So although it isn't possible to make avars optional in RestHeart, it's still possible to specify a wildcard as the value.

I'm not sure if there's a small performance hit by using a regular expression like this, but it seems to be the only simple way to do this for now.

Tom Kerswill
  • 421
  • 6
  • 10
  • hi im not able to send /.*/ from javascript. it is getting replaced by {}(empty object). can you please help? – shivadarshan Jan 09 '18 at 11:29
  • Re: sending /.*/ from javascript. This is probably interpreted as a regexp by javascript; so I think it would need to be escaped. You could try quoting it, or else using backslashes before each special character, to escape - like: \/.*\/ – Tom Kerswill Feb 08 '18 at 12:01
-1

You can have a conditional aggregation using the $cond operator

Evaluates a boolean expression to return one of the two specified return expressions.

The $cond expression has one of two syntaxes:

{ $cond: { if: <boolean-expression>, then: <true-case>, else: <false-case-> } }

Or:

{ $cond: [ <boolean-expression>, <true-case>, <false-case> ] }

Community
  • 1
  • 1
Andrea Di Cesare
  • 1,125
  • 6
  • 11
  • Perfect --- thanks! So in my use case, if the user gives a value for the "n" avar, then I went to include it in the match. If they don't give a value (which I guess means I'll need to pass an empty string, so ReSTHeart doesn't give an error), then I want to not include that in the match string. I think I'll probably need to do that using Regular expresions: $match: { _id: { "$cond": { if: { $eq: [ {_$var" : "n"}, "" ] }, then: "/.*/", else: {_$var" : "n"} } } } Does that look right --- or is there a way to do this without using a regex? – Tom Kerswill Apr 28 '17 at 09:31
  • I have looked further at this, and the $cond operator doesn't seem to be supported in the match section, so I don't think this solution is going to work. I have come up with an alternative using regular expressions (see below) – Tom Kerswill May 03 '17 at 14:11