Zend Gdata Calendar: setQuery with exact phrase match? - php

I am having trouble using Zend_Gdata_Calendar to return a subset of Google Calendar events with an exact phrase match.
The reference guide for Zend_Gdata_Books, in the setQuery() section, suggests this should be possible with Zend:
Note that any spaces, quotes or other punctuation in the parameter value must be URL-escaped (Use a plus (+) for a space). To search for an exact phrase, enclose the phrase in quotation marks. For example, to search for books matching the phrase "spy plane", set the q parameter to %22spy+plane%22.
As far as I can tell, Zend_Gdata_Books and Zend_Gdata_Calendar extend the same setQuery() function, so I figure they're equivalent on the Zend end of things.
As for Google, the Calendar query parameters reference says the Calendar API supports the standard Data API query parameters, which in turn says the full-text query string q supports case-insensitive exact phrase searching, just as Zend_Gdata_Books indicates.
I've tried it all these ways:
$gCal = new Zend_Gdata_Calendar();
$query = $gCal->newEventQuery();
$query->setQuery("%22event+text%22"); //no results
$query->setQuery("%22event%20text%22"); //no results
$query->setQuery("\"event text\""); //too many results
$query->setQuery('"event text"'); //too many results
$query->setQuery("event text"); //too many results
I realize the first two didn't work because the string is getting doubly URL-encoded. In the latter cases, I am getting the event I want, but also events including "event" or "text" that I don't want.
Could it be that Google has implemented the full-text query differently for the Calendar API? What kind of dumb things might I be doing on my end to break it?

it looks like you want try it with $query->setQuery('"event text"');
which yields the query string of Query string(19) "?q=%22event+text%22"
where $query->setQuery("event text");
yields the query string of Query string(13) "?q=event+text"
I used :
$gCal = new Zend_Gdata_Calendar();
$query = $gCal->newEventQuery();
$query->setQuery("event text");
Zend_Debug::dump($query->getQueryString(), 'Query');
To test.

Related

MATCH ... AGAINST doesn't come up with exact results

I'm working for the first time with MATCH...AGAINST in php sql but there is one bothering me and I can't figure out how to fix it. This is my code:
SELECT * FROM m_artist WHERE match(artist_name) against('". $_POST['article_content'] ."' IN BOOLEAN MODE)
And this is $_POST['article_content']:
Wildstylez Brothers Yeah Frontliner Waveliner
Now my output should be: Wildstylez, Frontliner and Waveliner cause that's in my database. And I do but besides that I also get the Vodka Brothers, 2 Brothers of Hardstyle and more cause of the word brothers. How do I fix that SQL only selects the literal match?
Full-text search actually is a quite misleading name: you can search the full text by your query (like google does) but it won't guarantee you, that the full text equals your query.
So, according to documentation on Boolean Full-Text Searches your input Wildstylez Brothers Yeah Frontliner Waveliner is interpreted as artist_name contains (at least) one of Wildstylez, Brothers, Yeah, Frontliner and Waveliner as word. This is why you get e.g. the Vodka Brothers, which contains Brothers. For google-like purposes this is just what you want, as you want to get details on something you only know part of as in show me articles on music.
You probably want to use
artist_name LIKE '%name_part1%' OR artist_name LIKE '%name_part2%' ...
or
artist_name IN ('exact_name1', 'exact_name2', ...)
simpliest case would be doing something like
$names = explode(' ', $_POST['article_content']);
$name_searches = array_map(function($a) {return 'artist_name = \''.mysql_real_escape_string($a).'\'';}, $names);
$sql = "SELECT * FROM m_artist WHERE ".implode(" OR ", $name_searches);
but you would loose the ability to find 2 Brothers of Hardstyle as the name itself contains a space.
Another approach can be to prefix all words by '+' and stick to MATCH() AGAINST() and you will find only artists which include every word given.
Please provide more context if this is not what you are looking for.

php mysql insert not working when including specific text

I have a text file that looks like this:
<http://dbpedia.org/resource/Autism> <http://www.w3.org/2000/01/rdf-schema#comment> "Autism is a disorder of neural development characterized by impaired social interaction and communication, and by restricted and repetitive behavior. The diagnostic criteria require that symptoms become apparent before a child is three years old. Autism affects information processing in the brain by altering how nerve cells and their synapses connect and organize; how this occurs is not well understood."#en .
<http://dbpedia.org/resource/Anarchism> <http://www.w3.org/2000/01/rdf-schema#comment> "Anarchism is generally defined as the political philosophy which holds the state to be undesirable, unnecessary, and harmful, or alternatively as opposing authority and hierarchical organization in the conduct of human relations. Proponents of anarchism, known as \"anarchists\", advocate stateless societies based on non-hierarchical voluntary associations. There are many types and traditions of anarchism, not all of which are mutually exclusive."#en .
<http://dbpedia.org/resource/Achilles> <http://www.w3.org/2000/01/rdf-schema#comment> "In Greek mythology, Achilles was a Greek hero of the Trojan War, the central character and the greatest warrior of Homer's Iliad. Plato named Achilles the most handsome of the heroes assembled against Troy. Later legends (beginning with a poem by Statius in the 1st century AD) state that Achilles was invulnerable in all of his body except for his heel. As he died because of a small wound on his heel, the term Achilles' heel has come to mean a person's principal weakness."#en .
I'm using code (not relevant here) to extract the name of the article in the first url in each line. Then I extract the first sentence of the description between quotes. The problem is when I try to insert that first sentence string into my table, the insert fails (echoing works fine). Just inserting the title without the description works fine. Does anyone have any idea why the description makes the insert fail?
Here's the code I'm using to get the first sentence:
$data = fgets($handle); //get line
$data = str_replace("> ", "-!-", $data);
dataArr = explode("-!-", $data);
//Get last part of uri from 1st element in array
$title = getLastPartOfUrl($dataArr[0]);
$desc=preg_replace('/(.*?[?!.](?=\s|$)).*/', '\\1', escape(substr($dataArr[2],1)));
$db->query("insert into mytable SET title = '".$title."', desc ='".$desc."'");
function escape($str)
{
$search=array("\\","\0","\n","\r","\x1a","'",'"');
$replace=array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
return str_replace($search,$replace,$str);
}
EDIT: I tried both urlencode and addslashes to no avail, in both cases including the $desc string makes the insert fail.
You don't escape the title.
I wouldn't trust your escape function either. I'm not sure what $db is, but you should use properly parameterized queries with PDO/mysqli
EDIT: DESC is a reserved word in MySQL. You need to surround it (when used as a column name) with backticks in your query.

how to implement the an effective search algorithm when using php and a mysql database?

I'm new to web design, especially backend design so I have a few questions about implementing a search function in PHP. I already set up a MySQL connection but I don't know how to access specific rows in the MySQL table. Also is the similar text function implemented correctly considering I want to return results that are nearly the same as the search term? Right now, I can only return results that are the exact same or it gives "no result." For example, if I search "tex" it would return results containing "text"? I realize that there are a lot of mistakes in my coding and logic, so please help if possible. Event is the name of the row I am trying to access.
$input = $_POST["searchevent"];
while ($events = mysql_fetch_row($Event)) {
$eventname = $events[1];
$eventid = $events[0];
$diff = similar_text($input, $event, $hold)
if ($hold == '100') {
echo $eventname;
break;
else
echo "no result";
}
Thank you.
I've noticed some of the comments mentioned more efficient ways of performing the search than with the "similar text" function, if I were to use the LIKE function, how would it be implemented?
A couple of different ways of doing this:
The faster one (performance wise) is:
select * FROM Table where keyword LIKE '%value%'
The trick in this one is the placement of the % which is a wildcard, saying either search everything that ends or begins with this value.
A more flexible but (slightly) slower one could be the REGEXP function:
Select * FROM Table WHERE keyword REGEXP 'value'
This is using the power of regular expressions, so you could get as elaborate as you wanted with it. However, leaving as above gives you a "poor man's Google" of sorts, allowing the search to be bits and pieces of overall fields.
The sticky part comes in if you're trying to search names. For example, either would find the name "smith" if you searched SMI. However, neither would find "Jon Smith" if there was a first and last name field separated. So, you'd have to do some concatenation for the search to find either Jon OR Smith OR Jon Smith OR Smith, Jon. It can really snowball from there.
Of course, if you're doing some sort of advanced search, you'll have to condition your query accordingly. So, for instance, if you wanted to search first, last, address, then your query would have to test for each:
SELECT * FROM table WHERE first LIKE '%value%' OR last LIKE '%value%' OR address LIKE '%value'
Look at below example :
$word2compare = "stupid";
$words = array(
'stupid',
'stu and pid',
'hello',
'foobar',
'stpid',
'upid',
'stuuupid',
'sstuuupiiid',
);
while(list($id, $str) = each($words)){
similar_text($str, $word2compare, $percent);
if($percent > 90) // Change percentage value to 80,70,60 and see changes
print "Comparing '$word2compare' with '$str': ";
}
You can check with $percent parameter for how strong match you want to apply.

zend search lucene query api: boosting a term

I am using zend search lucene, and would like to add boosts to some of my search terms.
The code is already written using the query construction API as follows.
$query->addTerm(new Zend_Search_Lucene_Index_Term($name,'name'), null);
I tried writing
$query->addTerm(new Zend_Search_Lucene_Index_Term($name . "^10", 'name'), null);
But that appears not to work correctly. (I suddenly get no results at all).
This carat syntax is listed in the documentation for query language, but not in the docs for query construction API. I know that in some instances the API doesn't behave quite like plain query language. Is this one of those instances?
Is there a function or parameter that adds boost values to terms?
Try outputting your query by doing something like this:
$term = new Zend_Search_Lucene_Index_Term($name,'name');
$query = new Zend_Search_Lucene_Search_Query_Term($term);
echo $query;
This will allow you to see the query that is being created before you use it to execute a search.

mysql "with rollup" query morphed into a tree structure

Background:
I have this "with rollup" query defined in MySQL:
SELECT
case TRIM(company)
when 'apple' THEN 'AAPL'
when 'microsoft' THEN 'MSFT'
else '__xx__'
END as company
,case TRIM(division)
when 'hardware' THEN Trim(division)
when 'software' THEN Trim(division)
else '__xx__'
END as division
,concat( '$' , format(sum(trydollar),0)) as dollars
FROM pivtest
GROUP BY
company, division with rollup
And it generates this output:
AAPL;hardware;$279,296
AAPL;software;$293,620
AAPL;__xx__;$572,916
MSFT;hardware;$306,045
MSFT;software;$308,097
MSFT;__xx__;$614,142
__xx__;__xx__;$1,187,058
If you have used "with rollup" queries in MySQL before, you can most likely infer the structure of my source table.
Question:
Given this raw output of MySQL, what is the easiest way to get a "tree" structure like the following?
AAPL
hardware;$279,296
software;$293,620
Total; $572,916
MSFT
hardware;$306,045
software;$308,097
Total;$614,142
Total
$1,187,058
Easiest is to do it in whatever client program you're using to receive and show the user MySQL's output -- definitely not easiest to implement presentation-layer functionality in the data layer!-) So tell us what language &c is in your client program and we may be able to help...
Edit: giving a simple Python client-side solution at the original asker's request.
With Python's DB API, results from a DB query can be most simply seen as a list of tuples. So here's a function to format those results as required:
def formout(results):
marker = dict(__xx__=' Total')
current_stock = None
for stock, kind, cash in results:
if stock != current_stock:
print marker.get(stock, stock).strip()
current_stock = stock
if kind in marker and stock in marker:
kind = ' '*8
print ' %s;%s' % (marker.get(kind, kind), cash)
marker is a dictionary to map the special marker '__xx__' into the desired string in the output (I'm left-padding it appropriately for the "intermediate" totals, so when I print the final "grand total", I .strip() those blanks off). I also use it to check for the special case in which both of the first two columns are the marker (because in that case the second column needs to be turned into spaces instead). Feel free to ask in comments for any further clarification of Python idioms and use that may be necessary!
Here's the output I see when I call this function with the supplied data (turned into a list of 7 tuples of 3 strings each):
AAPL
hardware;$279,296
software;$293,620
Total;$572,916
MSFT
hardware;$306,045
software;$308,097
Total;$614,142
Total
;$1,187,058
The space-alignment is not identical to that I see in the question (which is a little inconsistent in terms of how many spaces are supposed to be where) but I hope it's close enough to what you want to make it easy for you to adjust this to your exact needs (as you're having to translate Python into PHP anyway, the space-adjustment should hopefully be the least of it).

Categories