Using Greater Than In FQL Queries - error-handling

Can anyone tell me why this works:
https://graph.facebook.com/fql
?q=SELECT display_name FROM application WHERE app_id=0&access_token=...
(and returns 0 results, obviously)
but this doesn't:
https://graph.facebook.com/fql
?q=SELECT display_name FROM application WHERE app_id>=0&access_token=...
(HTTP 500)
The FQL pages on Facebook itself only ever give the simplest of queries - they never give samples of more complex queries involving strpos() and anything other than =.
I am aware of the need to work on an indexed column, but app_id is definitely one of those :)

If the column is indexable you still need to provide specific values for it.
If you could provide vague ranges (e.g. '>0') it would defeat the restriction of requiring you to specify the target objects first, and filter later

Related

Advanced search REST API

My requirement is to implement advanced search Rest API for searching the phones. The URI for the search API is http://myservice/api/v1/phones/search?q=${query_expression}
Where q is the complex query expression. Have the following questions
1) Since advanced search involves a lengthy query expression, the URI will not fit in a GET call. Is it alright to implement the search API via POST request and still maintain the RESTfulness?
2) I have come across the following implementations for the advanced search:
1st approach - Send the complete infix expression for the query expression.
eg.
PHONENAME STARTSWITH 'AR' AND ( PHONETYPE = '4G' OR PHONECOLOR = 'RED')
2nd approach - Constructing entire query expression in the form of a json.
eg.
{"criteria":[
{"index":1,"field":"PHONENAME","value":"AR","comparator":"STARTSWITH"},
{"index":2,"field":"PHONETYPE","value":"4G","comparator":"EQUALS"},
{"index":3,"field":"PHONECOLOR","value":"RED","comparator":"EQUALS"}
],"criteria":"( 1 AND (2 OR 3) )"}
3rd approach - Alternative way to implement the query expression as a json.
eg.
{"and":[
{"field":"PHONENAME","value":"AR","comparator":"STARTSWITH"},
"or":[
{"field":"PHONETYPE","value":"4G","comparator":"EQUALS"},
{"field":"PHONECOLOR","value":"RED","comparator":"EQUALS"}]
]}
Which approach would be considered more RESTful out of the three? Suggestions for any other approaches are welcome :)
You could follow the approach taken by ElasticSearch, which out of the examples you had given is the third one.
See https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html
The third approach is also easier to understand and easier to maintain.
For example if in the future you would need to add "fuzzy" query operator and it would have a completely different model, that would be an easy thing to do.
Yes, POST is a catch-all. It's preferable to use it for resource creation, but according to the spec it may be used in this way also. However, you should consider changing the endpoint to be /search-results. This gives you the flexibility to start storing search results later, and you can return a Location header pointing to the results of a particular complex query. Another alternative is to let users POST their search criteria, and then do a GET /search-results?criteria={id}.
Don't do the second one. It's hard to read and more complex than it should be. Either the first or the third are fine. The first is more compact but probably harder to handle on the back end. For the third, you really don't need the index.

Expanding an arbitrary Lucene Query

I am using Lucene 3.6.1. I receive a query from a user. This query may contain + or - operators, and may also contain phrases. In certain circumstances, I would like to expand the query by adding some extra terms that I compute. These terms are optional. However, any required include/exclude constraints specified by the user must be respected.
My initial strategy was to create a BooleanQuery, add a clause to it that contains the parsed user query, and then add further clauses that contain my expansion terms. The expansion terms would all be added as Occur.SHOULD. My question is how to constrain the user's query. I can imagine three possibilities:
The user's query contains no operators, which means I can include it as an Occur.SHOULD clause.
The user's query contains a + operator, so I need to include it as an Occur.MUST clause.
The user's query contains a - operator, but also other terms: Do I still include it as an Occur.MUST clause?
The question implicit in these three choices is how do I tell which condition is appropriate? I suppose I can rewrite the query and test for BooleanQuery instances, but that seems brittle.
I suppose can also try to tactic of creating a single string from the user's input and from my expansion terms, like this:
(fld1:userterm1 userterm2 -fld2:userterm3 +userterm4)^10 (fld1:expterm1)^8 (fld2:expterm2)^7 ...
Is this the best way to go? Or is there some elegant programmatic solution?
Okay, Not sure how useful this answer will be, but can't seem to come up with a hard and fast answer here, so I'll list a couple possibilities that come to mind:
First, a problem:
Modifying the query to look like:
(userquery) (other) (stuff)
I makes some sense to add the + with he rules you've shown, but a '-' prohibited term will be hard to respect correctly, since (query -prohibition) (other) will allow matches on other with prohibition present as well, and +(query -prohibition) (other) will require 'query' be matched.
The only way I see to really do that part right is to propagate the prohibited term into your automatically added terms as well, or extract it out to a parent query layer, more like (query -prohibition) --> (query) (other) -(prohibition).
And with user entered queries of arbitrary complexity, that may not be a great strategy.
If you want to tackle it by modifying the query string, then you should probably just add any terms to the end of the query. Nothing more to it.
I don't believe
(fld1:userterm1 userterm2 -fld2:userterm3 +userterm4)^10 (fld1:expterm1)^8 (fld2:expterm2)^7 ...
Is satisfactory, because userterm4 is only required within it's subquery, but a match Only on expterm1 is still acceptable. However, a query like:
fld1:userterm1 userterm2 -fld2:userterm3 +userterm4 (fld1:expterm1)^.8 (fld2:expterm2)^.7 ...
Should, I think, satisfy your needs, and prevents you from having to worry about the internals of your queryparser. I think this is the best approach.
I can also see logic in a query structured like
+(parsed userquery) (other stuff)
Effectively, always requiring a match on the user query. Lucene implicitly does this, in a sense, as it won't return a result that matches no term, even if no required fields are present in the query. This would then be using your added terms to impact scoring, rather than return a larger set of documents. This doesn't quite address what your asking, but might be worth considering.
If, despite the aforementioned problems of applying them, you still want to detect '+' and '-' operators, I think it can be reasonably assumed that a StandardQueryParser will return a BooleanQuery at base level for any query that you need to check for these operands on. You might have to worry about, for instance, DisjunctionMaxQueries, as well as what will happen when you have a simple query with an operator, like:
+myterm
I don't know if QueryParser would simply return a TermQuery, losing the plus (since it would be redundant without another term present). Concerns like that make me hesitant to address it in this way.
Similarly, attempting to detect these values from the query string must make assumptions about how things are parsed, and could become complicated.
To sumamrize, I think the best options are to, either: add terms to the end of the raw query string before doing any parsing, or treat the user query as atomic, and define the appropriate booleanclause independant of it's contents when adding to a boolean clause wrapping it with whatever other queries you need to include.

Hibernate and use of criteria method setFirstResult

I'm trying to learn the hibernate criteria API but I'm puzzled by the criteria method setFirstResult.
I don't understand why I would want to use it except in the rarest of circumstances. It seems to me that when I retrieve information from a database, I'm only interested in establishing some criteria and then executing the query against the criteria. Why do I care from which index number in the database the results should be read. It is not something I normally do when I write sql queries yet I see this method all over the hibernate literature. Is this method something I always have to invoke when writing Hibernate queries or can I safely ignore it?
Thank you,
Elliott
This is typically used when displaying paginated results of a query. The first page goes from 0 to 19, the second page from 20 to 39, etc.
Well I use it in a bunch of places.. its unfortunate or outright lucky/dumb that you have run into a case where you needed to page your results in which case you generally right queries that pick from one index to another. consider the case where you want to display the audit log of an app that is stored for every write action on the page. in that case you will show the 20 results based on which page the user is and what field the audit log is sorted on.

Query string with keys without values

What drawbacks can you think of if I design my REST API with query strings without parameter values? Like so:
http://host/path/to/page?edit
http://host/path/to/page?delete
http://host/path/to/page/+commentId?reply
Instead of e.g.:
http://host/api/edit?page=path/to/page
http://host/api/delete?page=path/to/page
http://host/api/reply?page=path/to/page&comment=commentId
( Edit: Any page-X?edit and page-X?delete links would trigger GET requests but wouldn't actually edit or delete the page. Instead, they show a page with a <form>, in which page-X can be edited, or a <form> with a Really delete page-X? confiramtion dialog. The actual edit/delete requests would be POST or DELETE requests. In the same manner as host/api/edit?page=path/to/page shows a page with an edit <form>. /Edit. )
Pleace note that ?action is not how query strings are usually formatted. Instead, they are usually formated like so: ?key=value;key2=v2;key3=v3
Moreover, sometimes I'd use URLs like this one:
http://host/path/to/page?delete;user=spammer
That is, I'd include a query string parameter with no value (delete) and one parameter with a value (user=spammer) (in order to delete all comments posted by the spammer)
My Web framework copes fine with query strings like ?reply. So I suppose that what I'm mostly wondering about, is can you think of any client side issues? Or any problems, should I decide to use another Web framework? (Do you know if the frameworks you use provides information on query strings without parameter values?)
(My understanding from reading http://labs.apache.org/webarch/uri/rfc/rfc3986.html is that the query string format I use is just fine, but what does that matter to all clients and server frameworks everywhere.)
(I currently use the Lift-Web framework. I've tested Play Framework too and it was possible to get hold of the value-less query strings parameters, so both Play and Lift-Web seems okay from my point of view.)
Here is a related question about query strings with no values. However, it deals with ASP.NET functions returning null in some cases: Access Query string parameters with no values in ASP.NET
Kind regards, Kaj-Magnus
Query parameters without value are no problem, but putting actions into the URI, in particular destructive ones, is.
Are you seriously thinking about "restful" design, and having a GET be a destructive action?

How can I filter out profanity in numeric IDs?

I want to use numeric IDs in a web application I am developing... However, as the ID is visible to users as a URL, I want to filter out profanity. Things like (I'll leave it to you to figure out what they are):
page.php?id=455
page.php?id=8008135
page.php?id=69
Has anyone solved this? Is this even a real problem?
Does it make sense just to skip numbers in my database sequence?
See also: How can I filter out profanity in base36 IDs?.
How about you using GUIDs? That would encode the actual numbers. I would bet most users don't even notice what is on the url.