SoftInstigate / restheart

Rapid API Development with MongoDB
https://restheart.org
GNU Affero General Public License v3.0
807 stars 171 forks source link

Error using "$and" / "&" on filter #83

Closed ghost closed 8 years ago

ghost commented 8 years ago

So i tried doing a query like this:

http -a a:a GET 127.0.0.1:8080/final/mydb?filter={'$and':[{'DATE_T':{'$gte':{'$date':'1444394813459'}}},{'DATE_T':{'$lte':{'$date':'1444395025082'}}}]}

and i get an error of illegal expression.

also tried this:

http -a a:a GET 127.0.0.1:8080/final/mydb?filter={'DATE_T':{'$gte':{'$date':'1444394813459'}}}&filter={'DATE_T':{ '$lte':{'$date':'1444395025082'}}}

but it only filters the first one...

any suggestions?

ujibang commented 8 years ago

Hi,

You have to take into account your interpreter that might get $var as a environment variable.

Try to single quote the filter '{...}'

You can also escape it: \$var

In you case try:

http -a a:a GET 127.0.0.1:8080/final/mydb?filter='{"DATE_T":{"$gte":{"$date":"1444394813459"}}}'\&filter='{"DATE_T":{ "$lte":{"$date":"1444395025082"}}}'
ghost commented 8 years ago

Hi, thank you for you answer ;)

using the & between the filters works for me but without the ' ' in the filters.

I am using this because I want all the results between 2 dates but i think that's not what is happening... Could you please point me into te right direction?

ujibang commented 8 years ago

In my case I need to use the ' otherwise operators starting with $ are replaced by the terminal with the empty string.

I created two documents with a date property

http -a a:a POST 127.0.0.1:8080/test/coll date:='{"$date": 1444394813459}'
http -a a:a POST 127.0.0.1:8080/test/coll date:='{"$date": 2444394813459}'

I can now query the collection to return docs between two dates.

You have two ways, either you specify a single filter param with $and operator

http -a a:a GET http://127.0.0.1:8080/test/coll?filter='{"$and":[{"date":{"$gte":{"$date":1443394813469}}}, {"date":{"$lte":{"$date":2443394813469}}}]}'

Or you use two filter qparams and RESTHeart will combine them with the $and operator for you:

http -a a:a GET http://127.0.0.1:8080/test/coll?filter='{"date":{"$gte":{"$date":1443394813469}}}'\&filter='{"date":{"$lte":{"$date":2443394813469}}}'

In both cases RESTHeart returns 1 document as expected:

HTTP/1.1 200 OK
...

{
    "_embedded": {
        "rh:doc": [
            {
                "_id": {
                    "$oid": "568108327d3126b74dc5f9b2"
                }, 
                "date": {
                    "$date": 1444394813459
                },
                ...
            }
        ]
    }, 
    "_id": "coll", 
    "_returned": 1, 
    ...
}
ghost commented 8 years ago

I tried your first option but it return "Bad Request" ...

On your second, like http -a a:a GET http://127.0.0.1:8080/final/mydb?filter={"date":{"$gte":{"$date":1444378063479}}}\&filter={"date":{"$lte":{"$date":1444378063480}}}

it returns dates outside the range.....

ujibang commented 8 years ago

Weird, it works for me.

Let's double check the terminal, please try this:

echo http -a a:a GET http://127.0.0.1:8080/final/mydb?filter={"date":{"$gte":{"$date":1444378063479}}}'\&filter='{"date":{"$lte":{"$date":1444378063480}}}

and paste here the output.

ghost commented 8 years ago

i have limited the answer to 2 results because otherwise it gives more than 100 results, and the second one is already out of range...

http -a a:a GET 127.0.0.1:8080/final/mydb?filter={'DATE_T':{'$gte':{'$date':'1444378063479'}}}\&filter={'DATE_T':{'$lte':{'$date':'1444378063480'}}}\&pagesize=2
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Location, ETag, Auth-Token, Auth-Token-Valid-Until, Auth-Token-Location, X-Powered-By
Auth-Token: 9b519daa-c3c8-49d7-81da-675f0cc9682f
Auth-Token-Location: /_authtokens/a
Auth-Token-Valid-Until: 2015-12-28T13:51:00.358Z
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 503
Content-Type: application/hal+json
Date: Mon, 28 Dec 2015 13:36:00 GMT
ETag: 567972b921d89e1d020c4a68
X-Powered-By: restheart.org

{
    "_collection-props-cached": false,
    "_created_on": "2015-12-22T15:56:41Z",
    "_embedded": {
        "rh:doc": [
            {
                "DATE_T": {
                        "$date": 1444378063479
},
…
},
{
            "DATE_T": {
                    "$date": 1444377872685
            },
...
}
]
}
"_etag": {
        "$oid": "567972b921d89e1d020c4a68"
    },
    "_id": "mydb",
    "_links": {
        "curies": [],
        "self": {
            "href": "/final/mydb?filter={DATE_T:{$gte:{$date:1444378063479}}}&filter={DATE_T:{$lte:{$date:1444378063480}}}&pagesize=2"
        }
    },
    "_returned": 2
ujibang commented 8 years ago

try this:

http -v -a a:a GET 127.0.0.1:8080/final/mydb?filter='{"$and":[{"DATE_T":{"$gte":{"$date":1444378063479}}},{"DATE_T":{"$lte":{"$date":1444378063480}}}]}'
ghost commented 8 years ago

http -v -a a:a GET 127.0.0.1:8080/final/mydb?filter={'$and':[{'DATE_T':{'$gte':{'$date':'1444378063479'}}},{'DATE_T':{'$lte':{'$date':'1444378065480'}}}]}

result: "http status code": 400, "http status description": "Bad Request", "message": "illegal filter paramenter: $and:[{DATE_T:{$gte:{$date:1444378063479}}}"

ujibang commented 8 years ago

you have to put the filter between ' and use " for keys.

please use my request

I found the bug when using two filter query parameters, however you should be able to use one filter qparam with $and.

I tested that request and works for me (returns 1 document. the one with two filter qparams actually returns 2 because one query overrides the other being both on the same property "DATE_T").

ghost commented 8 years ago

Thank you!

Your suggestion is working.. I just though that (") and (' ') could be used either way....

thank you for your support and fast response! ;)

ujibang commented 8 years ago

bug fixed https://softinstigate.atlassian.net/browse/RH-146

fix will be in 1.1.4

leonardorifeli commented 6 years ago

@ujibang I have the same problem. I'm sending a filter with: ?filter={'reviewer':{'Leonardo Rifeli'}. And the request are returning 400 (Bad Request) with blank response. Do you have any suggestion to solve that?

leonardorifeli commented 6 years ago

@ujibang resolved. Tks.