Search results with Sphinx and PHP by partial string - php

I am try to getting started with Sphinx. I add some results to index, download sphinxapi.php, and when I do this:
$cl = new SphinxClient();
$cl->SetServer( "localhost", 9312 );
// SPH_MATCH_ALL will match all words in the search term
$cl->SetMatchMode(SPH_MATCH_ALL);
$result = $cl->Query("test");
I getting this (row with id = 5 where title = test):
array (size=1)
5 => // id of post in database
array (size=2)
'weight' => string '2' (length=1)
'attrs' =>
array (size=0)
empty
But why I didnt get row from database with id = 6, where title field equal to test1 ?
And $cl->SetMatchMode(SPH_MATCH_ALL); fire error:
DEPRECATED: Do not call this method or, even better, use SphinxQL instead of an API
I comment this line in code of api file:
trigger_error ( 'DEPRECATED: Do not call this method or, even better, use SphinxQL instead of an API', E_USER_DEPRECATED );
But I dont know if it fine. Can somebody help me to understand what I am doing wrong? Thanks!

To get 'substring' matches, you need to specifically enable them.
http://sphinxsearch.com/docs/current.html#conf-min-prefix-len
(or min_infix_len)
If you dont want to see the depreciated notice, then set error_reporting
http://php.net/manual/en/function.error-reporting.php
(but even better is to rewrite the code to avoid calling the depreciated method)

warning setmatchmode
SetMatchMode are deprecated, you can still use it but it can be removed in next versions.
More info about it in:
http://sphinxsearch.com/docs/current.html#api-func-setmatchmode
http://sphinxsearch.com/blog/2013/09/11/deprecations-and-changes-in-the-2-2-series/
extracted from sphinx forum (barryhunter):
Changing the 'match mode' actually did TWO things, it changed the matching >behaviour - by
rewriting the query itself. AND changing the ranking mode.
By decoupling these concepts, I guess the idea is reduce confusion.
(for example, as soon as you choose a different matching mode, you can't >actully choose a
ranking mode)
... the match modes made sence before the 'extended syntax' was fully developed, but now
everything can be done directly via the extended syntax.
about search results
barryhunter answer is right
I suggest to read more about charset tables, morphology and stemming because i think are a better way to achieve success search than wilcard searches.
http://sphinxsearch.com/docs/current.html#conf-charset-table
http://sphinxsearch.com/docs/current.html#conf-morphology

Related

php include array vs mysql query: good idea?

I have an 2D array with a few sub-arrays (about 30, and sub-arrays have 10 elements).
I need to get quite frequently basic data from the array , I have a function that return the contents of it (or partial) all around my scripts. The function looks like:
function get_my_data($index = false){
$sub0 = array(
'something' => 'something',
'something else' => 'else',
...
);
$sub1 = array(
'something' => 'something different',
'something else' => 'else different',
...
);
...
$sub30 = array(
'something' => 'something 30 times different',
'something else' => 'else 30 times different',
...
);
$data = array($sub0,$sub1,$sub2,...,$sub30);
if($index !== false)
return $data[$index];
else
return $data;
?>
And then I call to it using include:
<?php
include 'my_data.php';
$id = $_GET['id'];
$mydata = get_my_data($id);
...
?>
I've done this because when I was starting this project, I didn't imagined I would have more that 10 sub-arrays, and I neither that I would need to have it dynamic. In fact, now I have to add a dynamic column (an index to sub-arrays) and it is not a great idea to use array declaration in this case. I immediately thought to use database, transferring data would not difficult, but if I do that, then I need to change my function get_my_data and insert a query in it, so, for it's called many times, I would have a lot of queries, pretty much every script of my website have one of it. I think performance would be worst (cause mysql is already largely used in my website). The dynamic data would change not too frequently (client do that).
The ideas I have to solve this problem are:
save all data in database and get it through mysql queries,
leave on php side and use files to manage dynamic data,
leave the static part on php side, add a logical connector (such 'id' index in sub-arrays) and id column in mysql database, and get the dynamic data on mysql
I don't want to lose much performance, do yo have any advice or suggestions?
Putting data like this in code is the worst possible plan. Not only do you create a whole bunch of junk and then throw out almost all of it, but if any of this changes it's a nightmare to maintain. Editing source code, checking it into version control, and deploying it is a lot of work to make a simple change to some data.
At the very least store this in a data format like JSON, YAML or XML so you can read it in on-demand and change a data-only file as necessary.
Ideally you put this in a database and query against it when necessary. Databases are designed to store, update, and preserve data like this.
You can also store JSON in the database, MySQL 5.7 even has a native column type for it, which makes this sort of thing even easier.

MongoDB: Different return values on .find() at shell access, and at php

I started to use MongoDB 2.4.4, and I have a very iritating case for query-ing some post, by field in php.
In the mongoshell, the db.posts.find({page_id:345671} (for example) gives me a 293 count of document.
The php equivalent:
$connection = new Mongo('mongodb://localhost:27017');
$db = connection->selectDB('post_db');
$posts = $db->posts->find(array('page_id' => 345671));
Alway return a zero, but, when the a find array is empty, it gives back the entire collection.
Also, ->explain() and .explain() gaves me different params.
What am I do wrong? There's no sharding, no indexes, just some test data, i'm in the begining of the things.
SOLVED, many thanks to Vitaly Muminov!
"i'm not quite sure about that, but you can try setting ini_set('mongo.native_long', 1); or wrapping your numbers into MongoInt64 class"
The solution is wrap the number to MongoInt64!

How to filter mongodb result for datatables?

I use this script to get the collection of my mongo database: http://datatables.net/development/server-side/php_mongodb
My question is: how to retrieve the rows where foo == 'mystring' only?
As you will notice (on line 29) from the source code in the file the mongo collection has been given the name: $m_collection as such:
$m_collection->find(array('foo' => 'mystring'))
Should work.
If this is not what you are looking for maybe you can be more specific and explain exactly what you are trying to do.
UPDATE
It has come to my attention you might want to instead edit the $searchTermsAll variable to search by this field in a doc. By the looks of it this PHP class links in the same as it would normally for SQL as such you should need to do anyhting special and can just enable filtering on datatables and add the value mystring to the foo field.
However to know if it is the right answer you will need to clarify.
UPDATE 2
A more destructive way of doing this that should keep filtering is to replace line 99 with:
$cursor = $m_collection->find(array_merge($searchTerms,
array('foo' => 'mystring')), $fields);
That will always make sure that your condition is added to the search terms but keeps the users own search terms.
Use as below
$cursor = $collection->find(array("foo" => "mystring"));
Here is more details: http://www.php.net/manual/en/mongo.queries.php

UpdateAttributes does not work

I have a problem with UpdateAttributes, it seem to not work for me.
When I issue:
$ret = $sphinx->UpdateAttributes ( "products", array ("status"), array(506607786 => array(10)) );
it returns 1, but search still returns status as old value for this.
When I try
$ret = $sphinx->UpdateAttributes ( "products", array ("status", "image_id"), array(506607786 => array(10, 6666)) );
it returns 0 (false)
Does this function even work ?
Ok I have found (sphinx docs are ugly) that when issuing updateAtrributes() from PHP app then I will not see the results in search command line. However one problem still
exist - I'm not able to update 2 attributes in one updateAtrributes() - seperatly they are fine - any clues why ?
When UpdateAttributes returns 0 (not false) it does not mean it didn't work, what it means is it didn't find anything to update, basically no updates commited. A return of -1 actually means this function did not work.
Make sure that 506607786 is actually an id in your Sphinx index and that products is the name of your index.
To make the question more helpful you can provide an example row from your table, preferrably the one used in this function defined as 506607786. You cna also provide a full set of your code to make it easier.
As a side note: UpdateAttributes does not act like a realtime index. You will need to filter on these attributes specifically in your query in order for sphinx to take their new values into consideration.

Zend Framework Mysql WHERE IN clause

Using the zend framework i have used a query,having a IN clause,this is my query
$select->where('p.brandid IN (?)',$details[brand]);
in the above query, $details[brand] has a value like this array(1,2,3) .
Actually the query has to return all the values which are all related to this array(1,2,3).
But my query is returning the result related to the first value present in the above array(1,2,3).ie 1 alone other 2,3 is not considered.
when i print this query it shows like this
[where] => Array
(
[0] => (p.brandid IN ('1,2,3'))
)
Can anyone show me what is the mistake i have made or solution for this..
This is because your query is getting formed wrongly p.brandid IN ('1,2,3') instead of p.brandid IN (1,2,3) you can try using implode function in php
$select->where('p.brandid IN (?)',implode(",",$details[brand]));
Just small research, because I have the same problem.
I am not sure what version of Zend do you use. But solution provided by #Omesh doesn't work with my version 1.12.
In my case it is absolutely opposite explode solution:
$select->where('p.brandid IN (?)', explode(',',$details[brand]));
Probably it depends on the type of $details['brand']. In my case I have string like 555,666,777,877. But even if you have array there. That is strange if Zend accept in your case string (result of implode) and does not accept array. And in my case it does not accept string but accept array.
You can modify this according to Zend framwork
locate(concat(',',$details[brand],','),concat(',',p.brandid,','))>0
Just use
$select->where->in('field_name', $your_simple_array);
If you using where() function with something criteria before, like
$select->where(['field_name' => $value]);
just use the first one after it, like
$select->where(['field_name' => $value]);
$select->where->in('field_name', $your_simple_array);
Always remember to use where not as a function where(), but just as a keyword.
This is valid and tested by me in the following context:
$select = $this->tableGateway->getSql()->select()->where(['field1' => $v1, 'field2' => $v2]);
$select->where->in('field_name', ['v1', 'v2', 'v3']);
That is, using these libraries in the beginning of the model class:
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Where;

Categories