How write solr query in PHP SOLR CLIENT - php

I use apache solr 3.6, and php solr client.
Now i do simple solr queries like
$query = 'url:"'.$searchSubject.'"';
where $searchSubject is one word.
But I want to make some queries with two or more words.
I don't understand how i must add some other parameters into code of PHP SOLR CLIENT.
Now i can add only query, offset , limit .
$response = $this->solr->search($query, $offset = 0, $limit = 10000);

You can just insert multiple words into the parameter $query using the format specified in lucene query parser syntax
$query = 'url:"' . $searchSubject . '"';
if you would like to search for two urls, the query can be
$query = 'url:("' . $searchSubject1 . '" OR "' . $searchSubject2 . '")';

In solr you can simply create query for multiple words.
$query = url:"($searchSubject1 $searchSubject2 $searchSubject3)";
space between $searchSubject1 and $searchSubject2 will take default OR condition.

Related

REPLACE version for PHP PDO using Microsoft Access database

I need to search for a word inside an MDB ACCESS database using PDO and PHP.
The problem is that inside the database I can have a field called CODE_NUMBER and it can contain dot or comma like:
12.11.34
The user when it search using a custom form for an article in database, maybe search without dots or other special chars... so in the example above, it can write inside the input box something like this:
1211
Then press enter.
I'd like to get 12.11.34 as a valid result in this case, ignoring search for dot.
The problem is that PDO for MDB ACCESS doesn't support REPLACE command:
This version for mysql is working:
$code = "1211";
$rs = $db->prepare('SELECT Products.* FROM Products WHERE REPLACE(Products.CODE_NUMBER, ".", "") LIKE ?');
$rs->execute(array("%" . $code . "%"));
$ris = $rs->fetchAll(PDO::FETCH_ASSOC);
But the same one using MDB access doesn't work!
So I tried this way from here: Search using REPLACE in a SELECT with PDO and .MDB ACCESS, with PHP
$code = "1211";
$code = implode("[.]", str_split($code )) . "[.]";
$rs = $db->prepare('SELECT Products.* FROM Products WHERE Products.CODE_NUMBER LIKE ?');
$rs->execute(array("%" . $code . "%"));
$ris = $rs->fetchAll(PDO::FETCH_ASSOC);
But it doesn't work.
Any suggest?

How to fix 504 Gateway Time-out nginx error in sql query?

I am beginner and I am trying update tables in Joomla (3.8) database and I get 504 Gateway Time-out nginx error at the following sql query:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$condition = array(
$db->quoteName('B.virtuemart_product_id') . ' >= '.$product_id_from,
$db->quoteName('B.virtuemart_product_id') . ' <= '.$product_id_to);
$query->select(array('B.virtuemart_product_id, A.product_sku,
A.price_CZK, A.price_EUR'))
->from($db->quoteName('#__watrex_price_list_temp', 'A'))
->join('INNER' , $db->quoteName('#__virtuemart_products', 'B') . '
ON (' . $db->quoteName('B.product_sku') . ' = ' . $db-
>quoteName('A.product_sku') . ')')
->where($condition,'AND');
$db->setQuery($query);
$num_rows = $db->getNumRows();
$results = $db->loadObjectList();
...
Result can contain up to 50000 items. How can I fix this problem? Thank you
I suspect that getNumRows() is the culprit here. When I run call echo $db->getNumRows() on my localhost with a successful query returning a non-empty result set to replicate the issue, I get:
Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, null given in C:\wamp64\www\blah\libraries\joomla\database\driver\mysqli.php on line ###
NULL
To fix this, add $db->execute(); on the line before $db->getNumRows() and everything works happily and as desired. That said, I recommend just calling count() or sizeof() on $results because you'll get the same output without having to add the execute() call.
If that isn't the cause, this may or may not be within your control. You may wish to work through this checklist of advice: https://www.lifewire.com/504-gateway-timeout-error-explained-2622941
As for how to process your result set with less memory consumption, you might entertain James Garrett's suggestion.
As for subtle refinements to your query:
Your SELECT clause renders appropriately, but the syntax seems to be designed with the intent to create an array of columns. Truth is, you have a single-element array containing all four columns. This only becomes problematic if you decide to apply quoteName() to the array.
I recommend lowercase table aliases so that they do not "catch the eye" as MySQL keywords. SQL Queries - Paragraph 1
The ON declaration doesn't need to be parenthetically wrapped.
None of your tables or columns actually need quoteName() to be called on them to maintain stability/security. You may choose to omit them to make your code easier to read, but the Joomla coding standards demand 100% employment of the call (I personally dislike this stance). SQL Queries - Paragraph 5
Table names and table column names should always be enclosed in the quoteName() method to escape the table name and table columns.
It may not aid in performance, but BETWEEN is "inclusive" and is specifically designed to do what your two WHERE conditions require. https://www.techonthenet.com/mysql/between.php
My recommended snippet:
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName(["b.virtuemart_product_id", "a.product_sku", "a.price_CZK", "a.price_EUR"]))
->from($db->quoteName("#__watrex_price_list_temp", "a"))
->innerJoin($db->quoteName("#__virtuemart_products", "b") . " ON " . $db->quoteName('b.product_sku') . " = " . $db>quoteName("a.product_sku"))
->where($db->quoteName("b.virtuemart_product_id") . " BETWEEN " . (int)$product_id_from . " AND " . (int)$product_id_to);
$db->setQuery($query);
if (!$results = $db->loadObjectList()) {
echo "No Rows";
} else {
// if you need to know the count...
echo count($results);
// iterate the result set
foreach ($results as $row) {
// ... yatta-yatta ...
}
}
If ALL of the above fails, I recommend a re-think of your project. Perhaps you should be reducing the result set volume with LIMIT and using pagination techniques if necessary.
p.s. Rick James has some excellent advice about adding indexes.

How to use postGIS with CakePHP 3

We're running CakePHP v3.x with a Postgres database. I need to select some records whose latitude and longitude are within X distance from another point. PostGIS has a function that does just this but it seems that I have to right raw SQL queries in order to use it.
I'm not asking for help writing the raw query, but I am looking for confirmation as to whether the raw query approach is the correct way to use this extension while making best use of the framework. I searched and haven't found any libraries to extend the CakePHP ORM to include this. Perhaps there's a third option I haven't thought of.
[NOTE: This does not work...]
public function fetch()
{
$maxMetersAway = 10 * 1000;
$lat = $this->request->query['lat'];
$lng = $this->request->query['lng'];
$stops = $this->Stops->find('all')
->where("ST_DWithin( POINT($lng,$lat), POINT(Stops.lng,Stops.lat), $maxMetersAway")
->toArray();
$this->set(['stops'=>$stops, '_serialize' => true]);
}
I got the CakePHP query working with this:
$stops = $this->Stops->find('all')
->where(['ST_DWithin( ST_SetSRID(ST_MakePoint(' . $longitude . ', ' . $latitude . '),4326)::geography, ST_SetSRID(ST_MakePoint(Stops.longitude, Stops.latitude),4326)::geography, ' . $maxMetersAway . ')'])
->toArray();
Updated: Original didn't actually work with the $maxMetersAway properly.

Database search like google [duplicate]

This question already has answers here:
Google-like Search Engine in PHP/mySQL [closed]
(9 answers)
Closed 1 year ago.
I currently have a search option on my PHP+MYSQL website.
The MYSQL query is currently something like "SELECT pageurl WHERE name LIKE '%$query%'.
The reason I posted here is because I noticed that if the name of one of my products is "Blue Bike" and someone looks for "Bike Blue", no results are returned.
I am looking for a solution to this because I know that if I type on google same word, something appears.
I was thinking to create a PHP function to mix up all the words from the query if the query is having 4 or fewer words, generating around 24 queries.
Is there an easier solution to this?
Thanks for your time
As to not let this go without a working answer:
<?php
$search = 'this is my search';
$searchSplit = explode(' ', $search);
$searchQueryItems = array();
foreach ($searchSplit as $searchTerm) {
/*
* NOTE: Check out the DB connections escaping part
* below for the one you should use.
*/
$searchQueryItems[] = "name LIKE '%" . mysqli_real_escape_string($searchTerm) . "%'";
}
$query = 'SELECT pageurl FROM names' . (!empty($searchQueryItems) ? ' WHERE ' . implode(' AND ', $searchQueryItems) : '');
?>
DB connections escaping
mysqli_:
Keep using mysqli_real_escape_string or use $mysqli->real_escape_string($searchTerm).
mysql_:
if you use mysql_ you should use mysql_real_escape_string($searchTerm) (and think about changing as it's deprecated).
PDO:
If you use PDO, you should use trim($pdo->quote($searchTerm), "'").
use full text search instead of like
full text search based on indexed text and is very faster and beter than using like.
see this article for more information about full text search
What you are looking for is fulltext search.
Try Sphinx, it is very fast and integrates well with MySQL.
Sphinx website
I wrote a function that approaches Google's operation taking into account the double quotes for the elements to search as a whole block. It does NOT take into account the - or * instructions.
table: MySQL table to consider
cols: array of column to parse
searchParams: search to process. For example: red mustang "Florida 90210"
function naturalQueryConstructor($table, $cols, $searchParams) {
// Basic processing and controls
$searchParams = strip_tags($searchParams);
if( (!$table) or (!is_array($cols)) or (!$searchParams) ) {
return NULL;
}
// Start query
$query = "SELECT * FROM $table WHERE ";
// Explode search criteria taking into account the double quotes
$searchParams = str_getcsv($searchParams, ' ');
// Query writing
foreach($searchParams as $param) {
if(strpos($param, ' ') or (strlen($param)<4)) {
// Elements with space were between double quotes and must be processed with LIKE.
// Also for the elements with less than 4 characters. (red and "Florida 90210")
$query .= "(";
// Add each column
foreach($cols as $col) {
if($col) {
$query .= $col." LIKE '%".$param."%' OR ";
}
}
// Remove last ' OR ' sequence
$query = substr($query, 0, strlen($query)-4);
// Following criteria will added with an AND
$query .= ") AND ";
} else {
// Other criteria processed with MATCH AGAINST (mustang)
$query .= "(MATCH (";
foreach($cols as $col) {
if($col) {
$query .= $col.",";
}
}
// Remove the last ,
$query = substr($query, 0, strlen($query)-1);
// Following criteria will added with an AND
$query .= ") AGAINST ('".$param."' IN NATURAL LANGUAGE MODE)) AND ";
}
}
// Remove last ' AND ' sequence
$query = substr($query, 0, strlen($query)-5);
return $query;
}
Thanks to the stackoverflow community where I found parts of this function!
To have a google like search you'd need many database and index nodes, crazy algorithms.. now you come up with a SELECT LIKE ... lol :D
MySQL is slow in searching, you'd need fulltext and index set properly (MyISAM or Aria Engine). Combinations or different entities to search for are almost not implementable properly AND fast.
I'd suggest to setup an Elasticsearch server which is based on Apache's Lucene.
This searchs very fast and is easy to maintain. And you would not have to care about SQL injection and can still use the mysql server fast.
Elasticsearch (or other Lucene based search engines like SolR) can easily be installed on any server because they are written in Java.
Good documentation:
http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/
I would do an explode first:
$queryArray = explode(" ", $query);
and then generate the SQL query something like:
for ($i=0; $i< count($queryArray); $i++) {
$filter += " LIKE '%" + $queryArray[$i] + "%' AND" ;
}
$filter = rtrim ($filter, " AND");
$sql = "SELECT pageurl FROM ... WHERE name " + $filter
(note: haven't tested/run this code)

Expression Engine: Database Query Not Executing As Expected

I've setup an EE template with PHP enabled and set the PHP Parsing Stage as Input. I would expect the following code to update the database correctly, but nothing happens:
<?php
$ids= "{last_segment}";
$userId = "{member_id}";
$sql = "UPDATE table SET column = '" . $ids . "' WHERE member_id = '" . $userId . "'";
$this->EE->db->query($sql);
?>
If I echo my query it looks correct, and in fact if I run it in PHPMyAdmin it works fine. Is there something I'm missing? Do I need to modify the PHP Parsing Stage?
Thanks in advance!
Looks like you may just need parentheses after "EE":
$this->ee()->db->query($sql);
Also, I'm not sure if you need $this...
http://ellislab.com/expressionengine/user-guide/development/usage/database.html

Categories