is there a way to optimize this kind of query? - overpass-api

I'm trying to fetch results with Overpass API, while I worked hard to find the right syntax, now I figured that there was different syntax for same results. But the difference of response time is important.
For now, my best way to request what I need is this query:
(
node["natural"~"peak|saddle|bay|beach|cape|glacier|reef|cliff|dunehill|valey|volcano"];
node["place"~"suburb|village|town|city"];
node["leisure"~"nature_reserve|park|track|summer_camp|stadium|marina|horse_riding|golf_course|beach_resort"]; rel["natural"~"peak|saddle|bay|beach|cape|glacier|reef|cliff|dunehill|valey|volcano"];
rel["place"~"suburb|village|town|city"];
rel["leisure"~"nature_reserve|park|track|summer_camp|stadium|marina|horse_riding|golf_course|beach_resort"];
);
(._;>;);
out body center tags;
while this same answer with this query will take double time of response:
(
node[natural=peak];
node[natural=saddle];
node[natural=bay];
node[natural=beach];
node[natural=cape];
node[natural=glacier];
node[natural=reef];
node[natural=cliff];
node[natural=dune];
node[natural=hill];
node[natural=valley];
node[natural=volcano];
node[tourism=wilderness_hut];
node[place=suburb];
node[place=village];
node[place=town];
node[place=city];
node[leisure=nature_reserve];
node[leisure=park];
node[leisure=track];
node[leisure=summer_camp];
node[leisure=stadium];
node[leisure=marina];
node[leisure=horse_riding];
node[leisure=golf_course];
node[leisure=beach_resort];
);
(._;>;);
out body;
(
rel[natural=peak];
rel[natural=saddle];
rel[natural=bay];
rel[natural=beach];
rel[natural=cape];
rel[natural=glacier];
rel[natural=reef];
rel[natural=cliff];
rel[natural=dune];
rel[natural=hill];
rel[natural=valley];
rel[natural=volcano];
rel[tourism=wilderness_hut];
rel[place=suburb];
rel[place=village];
rel[place=town];
rel[place=city];
rel[leisure=nature_reserve];
rel[leisure=park];
rel[leisure=track];
rel[leisure=summer_camp];
rel[leisure=stadium];
rel[leisure=marina];
rel[leisure=horse_riding];
rel[leisure=golf_course];
rel[leisure=beach_resort];
);
(._;>;);
out center tags;
Is there a way to improve the first query more than I already did? Thanks

Related

Reject method of collection does not work

Route::get('/product',function(){ $product = Product::all(); $filtered_product = $product->reject(function ($product) { $specific_product = $product->where("price",'=',"10.00")->get(); foreach($specific_product as $sp){ return $sp->price; } }); dd($filtered_product); });
I want to exlude some records which match the condition above. I know I can do it in simpler way, but I have a weird habit which I like to do thing in more complex way, So I can be proud of myself.. sound crazy right?...anyway..why the code above return an empty array??? please don't tell me to read the document. I am here because I have read it a thousand time and I still don't get it. thanks
I expect the result which does not include the records which have price 10.00

Import URL return values

I'm trying to import data from a quantum random number generator and load it into a table:
https://qrng.anu.edu.au/API/jsonI.php?length=10&type=uint8&size=1
The results, if you were to run the URL in a browser, look exactly like this:
{"type":"uint8","length":10,"data":[76,104,98,90,47,116,250,86,43,108],"success":true}
It's just a string return that I can easily parse...but all I see when searching for how to do this is XML and JSON stuff. I don't need that. I just want to execute a simple URL and parse the string return value...but it's got me stumped.
You haven't provided enough sample data to offer a complete answer but here's some sample code that will get you close:
DECLARE #string VARCHAR(8000) = 'https://qrng.anu.edu.au/API/jsonI.php?length=10&type=uint8&size=1';
SELECT NewString =
'{'+STRING_AGG(CONCAT('"',SUBSTRING(s.Item,1,idx.N-1),'":')+
ISNULL(CAST(TRY_CAST(f.S AS INT) AS VARCHAR(8000)), CONCAT('"',f.S,'"')),',')+'}'
FROM (VALUES(SUBSTRING(#string,CHARINDEX('?',#string)+1,8000))) AS ns(NewString)
CROSS APPLY dbo.DelimitedSplit8K(ns.NewString,'&') AS s
CROSS APPLY (VALUES(CHARINDEX('=',s.Item))) AS idx(N)
CROSS APPLY (VALUES(SUBSTRING(s.Item,idx.N+1,8000))) AS f(S);
Returns:
{"length":10,"type":"uint8","size":1}

How to avoid affecting other queries when using posts_orderby?

In WordPress as you must already known, when using get_posts() or query_posts() or even WP_Query, it is not possible to order the returned posts by specifying a list of post ID in the order we want.
Instead we have to loop through the results and re-order them on the PHP side. This is a performance hit and a bad practice. Instead we should use built-in MySQL functions to retrieve the posts in the desired order upfront.
Thankfully there is the posts_orderby which can be used to specify a custom ORDERBY statement, like this:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
global $my_post_ids;
$orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
However there is a problem with the above code, is that it will affect the order of all queries on the page! Including queries made by plugins, shortcodes, and so on.
Easy fix!
The simple way to fix this, is to apply the filter only one time, and remove it as soon as it is called, by putting a remove_filter() within the filter itself, so it is run only once:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
// Disable this filter for future queries!
remove_filter(current_filter(), __FUNCTION__);
global $my_post_ids;
$orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
Because I set this filter just before my custom query, once I execute my custom query it should be filtered by the posts_orderby filter set above, which is then immediately disabled so it won't affect any future queries.
In theory, that's great, and it works great in most case scenarios!
An issue with WPML
However I have encountered a case when using the WPML plugin where this filter affects other queries than mine and causes errors. I believe the WPML plugin is creating a query of its own that is executed just before my own custom query, making my filter applies to the WPML query instead of mine!
Is there any possible way to add a check within the filter to make sure that it affects the correct query?
Thank you very much
Edit:
The fix for WPML
For information, while the accepted answer for this question is correct, it didn't solve the problem I was having with WPML. Here is how I fixed the WPML conflict:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
// Disable this filter for future queries!
remove_filter(current_filter(), __FUNCTION__);
global $my_post_ids, $wpdb;
$orderby_statement = 'FIELD('.$wpdb->base_prefix.'posts.ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
This filter takes two parameters, $orderby and &$this. "this" being the WP_Query object. I'm not sure how to detect that WPML is making the call, but we can check that your call is the one being
made.
$my_post_ids = array(1,3,2);
add_filter( 'posts_orderby', 'my_custom_orderby', 10, 2 );
function my_custom_orderby( $orderby_statement, $object )
{
global $my_post_ids;
if( $my_post_ids != $object->query['post__in'] )
return $orderby_statement;
// Disable this filter for future queries!
remove_filter( current_filter(), __FUNCTION__ );
$orderby_statement = 'FIELD(ID, ' . implode( ',', $my_post_ids ) . ')';
return $orderby_statement;
}

Different FQL results

If I run this query with the php sdk:
$fql ="http://graph.facebook.com/fql?q=SELECT+id,+text,time,+fromid+FROM+comment+WHERE+post_fbid+=+414571855318181+AND+is_private+=+0+AND+object_id+IN+%28SELECT+comments_fbid+FROM+link_stat+WHERE+url+=+%22http://griekenland.net/actie-pagina/%22%29";
$fql_query_result = file_get_contents($fql);
$fql_query_obj = json_decode($fql_query_result, true);
I get this response, which I think is wrong. Because it should filter on is_private and the comment hasn't been approved yet, so I don't see why it should return it.
Array
(
[data] => Array
(
[0] => Array
(
[id] => 394048867370480_2458709
[text] => Kefalonia vind ik zo overweldigend mooi en afwisselend......speechless :O
[time] => 1375532512
[fromid] => removed
)
)
)
Now when I enter the same query directly in the browser http://graph.facebook.com/fql?q=SELECT+id,+text,time,+fromid+FROM+comment+WHERE+post_fbid+=+414571855318181+AND+is_private+=+0+AND+object_id+IN+%28SELECT+comments_fbid+FROM+link_stat+WHERE+url+=+%22http://griekenland.net/actie-pagina/%22%29 then it shows the expected response, which is nothing.
How can there be a difference like this? I mean it's either private or not? And I'm pretty sure the FQL call through php used to give the correct response until somewhere last week. If anyone knows what could possible cause this difference I would like to know :)
Have you tried using can_like instead? That should give you an idea of whether it's approved or not.

Sorting Topscorecollector Results in Lucene.net?

I am doing a search operation by using lucene where i was taking my results by using topscorecollector, but i found that it unable to sort my topscorecollector results. I found it quiet odd to sort that. Can we sort the TopscoreCollector results?
My code looks like this
TopScoreDocCollector collector = TopScoreDocCollector.create(100, true);
indexSearch.Search(andSearchQuery, filter, collector);
ScoreDoc[] hits = collector.TopDocs().scoreDocs;
for (int i = 0; i < hits.Length; i++)
{
int docId = hits[i].doc;
float score = hits[i].score;
Lucene.Net.Documents.Document doc = indexSearch.Doc(docId);
document.Add(doc);
}
Can anybody help me?
Also one more doubt
we can sort the search results like this
Hits hits = IndexSearch.search(searchQuery, filter, sort);
But it is showing that Hits become obselete by Lucene 3.0. so i have opted for TopscoreCollector. But now iam very much confused?
If anyother alternate method for Hits, Please pass that to me...
TopScoreDocCollector will return results sorted by score. To get results sorted on a field you will need to use a method overload that returns TopFieldDocs.
IE: IndexSearcher.Search(query, filter, nResults, sort)
If you dont want to limit the number of results use a very large value for the nResults parameter. If i remember correctly passing Int32.MAX_VALUE will make Lucene generate an exception when initializing its PriorityQueue but Int32.MAX_VALUE-1 is fine.