sphinx - which id to which index? - php

I'm using sphinx to search our database. In this example, I'm querying two indexes; index1 and index2.
$res = $cl->Query( $query, "index1 index2" );
The results are good, but I can't distinguish the resulting IDs from index1 and index2 from within the code. Is there a way I can make all IDs coming from index1 look like: in1_1, in1_600, in1_x... So I can distinguish between them?

Just setup a attribute that identifies which index it came from, see
http://sphinxsearch.com/forum/view.html?id=5653

Related

enum values from mysql table

I have a enum column in my table and I am trying to get out the values I have set in the table in a drop down. So first I have written this query to get the column_type and column_name
"SELECT `COLUMN_NAME`,`DATA_TYPE`,`COLUMN_TYPE` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA`='devsbh' AND `TABLE_NAME`='modules' AND `COLUMN_NAME` NOT IN ('created_at', 'updated_at')"
then I do this to get out the enum values like so
<?php
$regex = "/'(.*?)'/";
preg_match_all( $regex , $modules->COLUMN_TYPE , $enum_array );
$enum_fields = $enum_array[1];
?>
and I display like so
PS:Using laravel's blade template engine.
{!! Form::select($modules->COLUMN_NAME,$enum_fields) !!}
Everything is correct up until here. When I try to store it tries too save as for Y => 0 and for N => 1. How can I get the key => value same as enum value?
the values of $enum_fields as per the console is [0]=>Y , [1]=>N.
You can use the array_combine method to make the key and the value of the array same like so
<?php
$regex = "/'(.*?)'/";
preg_match_all( $regex , $modules->COLUMN_TYPE , $enum_array );
$keyValueSame = array_combine($enum_array[1],$enum_array[1]);
?>
now the key and value of the $keyValueSame array will have the same value.
the values of $keyValueSame as per the console is [Y]=>Y , [N]=>N.
You are probably better off just hard coding the enumerations into your codebase.
Assuming you are using MySQL, the idea behind enumerations is really to restrict the values in the column to a specific set - basically saying "if the value is not one of these strings, don't allow it.".
Enumerations are not designed to be changed often (if at all) - in fact, you may find issues if you do try to alter them it - it can take some database gymnastics to alter them especially if you have lots of records.
If your "lookup" data will change, and you need it to be database stored, make the column a foreign key to another table containing your lookup fields.
If you are stuck with the enumerations, just hard code the list in your dropdown.

Searching a particular index using Sphinx, from multiple indexes, through PHP script

I have multiple sources, like this (say)
source src1{
...
}
source src2{
...
}
AND
index src1{
...
}
index src2{
...
}
src1 has sql query from one individual table and src2 has sql query based on another individual table.
Now, in the PHP script, how do I specify, which indexer to use?
Normally, in the PHP script, we write it this way
$ss = new SphinxClient;
$ss->setServer("localhost", 9312);
$ss->setMatchMode(SPH_MATCH_ANY);
Since, there is no mention about the indexer being used. It's useless to search both indexes (i.e., both tables). I want to search the index src2(say) i.e., data from the second table. So, how do I specify this in my php script, that sphinx should search only that particular indexer.
The Query call includes the index(s) to search
$res = $cl->Query($query,"src1");
For one index (per Barry Hunter)
$res = $cl->Query($query,"src1");
or
For multiple indexes for one query.
$res = $cl->Query($query,"src1 src2 src3 src4");

Having difficulties sorting data from mysql query using php

This code is used to get a specific list of ID's from one table, then use those ID's to get the information from another table. Once I get all the information from the 2nd table, I am attempting to sort the data alphabetically based on a field in the 2nd table.
Example, I am getting the name based on a correlating ID and then want to display the entire result in alphabetical order by name (artist_name).
Here is the code I have. When I execute this without the sort(), it works fine but is not in alphabetical order. When I add the sort() in the 2nd while statement, the page looks the same but the name and other data do not display. The source code in the browser shows that the results are being accounted for but the sort must be preventing the variables or information from being displayed for some reason.
I haven't used a sort function before and I tried looking at some examples but couldn't really find something specific to my situation. Any and all help would be greatly appreciated. I have already looked at the PHP manual for sort so no need to send me a link to it ;-)
<?php $counter = 0;
$artistInfo = mysql_query("SELECT DISTINCT event_url_tbl.artist_id FROM event_url_tbl WHERE (SELECT cat_id FROM artist_tbl WHERE artist_tbl.artist_id = event_url_tbl.artist_id) = 1");
while ($aID = mysql_fetch_array($artistInfo))
{
$getArtistInfo = mysql_query("SELECT * FROM artist_tbl WHERE artist_id = '" . $aID['artist_id'] . "'");
while($artist = mysql_fetch_array($getArtistInfo))
{
sort($artist);?>
<a class="navlink" href="<?=HOST?><?=$artist['page_slug']?>/index.html">
<?=$artist['artist_name']?>
</a><br />
<?php }
}
?>
Your best bet, as a commenter mentioned, is to use an ORDER BY clause in SQL.
SELECT *
FROM artist_tbl
WHERE artist_id = XXX
ORDER BY artist_name ASC
The other commenter who suggested using PDO or mysqli is also correct, but that's a different issue.
To answer your specific question about sorting, according to the manual,
Blockquote Note: This function assigns new keys to the elements in array. It will remove any existing keys that may have been assigned, rather than just reordering the keys.
This means all of your array keys ('page_slug', 'artist_name', etc) are wiped out. So when you try to refer to them later, there is no data there.
Were you to use this method, you would want to use asort to sort an associative array.
However, you don't want to use sort here. What you're sorting is the variables for one row of data (one individual artists), not all of your artists. So if you think of each artist row as an index card full of data (name, id#, page slug, etc) all you're doing is moving those items around on the card. You're not reorganizing your card catalog.
Using an order by clause in the SQL statement (and rewriting in PDO) is your best bet.
Here is how I would rewrite it. I have to take some guesses at the SQL because I'm not 100% sure of your database structure and what you're specifically trying to accomplish, but I think this would work.
$query_str = "
SELECT
artist.name,
artist.page_slug
FROM
artist_tbl AS artist
INNER JOIN event_tbl AS event
ON event.artist_id = artist.artist_id
WHERE
artist.cat_id = 1
ORDER BY
artist.name ASC";
$db_obj = new PDO (/*Connection stuff*/);
$artists_sql = $db_obj->prepare ($query_str);
$artists_sql->execute ();
while ($artist = $artists_sql->fetch (PDO::FETCH_ASSOC)) {
$return_str .= "<a class='navlink' href='{HOST}
{$artist['page_slug']}/index.html'>
{$artist['artist_name']}</a><br/>";
}
echo $return_str;
In all honesty, I would probably create an artist class with a display_link method and use PDO's fetchObject method to instantiate the artists, but that's getting ahead of ourselves here.
For now I stuck with procedural code. I don't usually like to mix my HTML and PHP so I assign everything to a return string and echo it out at the end. But this is close to what you had, using one SQL query (in PDO - seriously worth starting to use if you're creating new code) that should give you a list of artists sorted by name and their associated page_slugs.
You could do all of this in one query:
SELECT * FROM event_url_tbl AS event
INNER JOIN artist_tbl AS artist ON event.artist_id = artist.id
ORDER BY artist.name DESC;
This cuts out a lot of the complexity/foreaches in your script. You'll end up with
Label1 (Label 1 details..) Artist1 (Artist1 details..)
Label1 (Label 1 details..) Artist2 (Artist1 details..)
Label2 (Label 2 details..) Artist3 (Artist1 details..)
Always good to bear in mind "one query is better than many". Not a concrete rule, just if it's possible to do, try to do it. Each query has overheads, and queries in loops are a warning sign.
Hopefully that helps

How do I search Full text with partial matches?

I have a table, with not many rows, and neither many columns. I am doing a Full text search on 3 columns.
My code is
$search_input = trim($_GET['s']);
$search = mysql_real_escape_string($search_input);
$search = '+'.str_replace(' ', '* +', $search).'*';
$sql = "SELECT * FROM table WHERE
MATCH(def, pqr, xyz) AGAINST ('$search' IN BOOLEAN MODE)";
$result = mysql_query($sql);
I can correctly search for terms like abcdefgh, which are present as ... abcdefgh ....
But I am receiving empty set with search terms like abc, where in table entry is present something like abc-123, and also terms like abcdefghs. (notice this is plural of above)
Clearly I need to implement partial search, or something like that.
But how do I implement such a search? Any better way to do a entire table search on user input?
Do mention anything I am doing incorrectly.
EDIT : By adding * after each word, now I am able to also search for abcde, but above problems remains.
Do you mean you don't get results for 3 letter combinations? If so, you might be hitting the mysql index length (which is usually set to 3)
More info here - http://dev.mysql.com/doc/refman/5.1/en/fulltext-fine-tuning.html

Match whole field in Lucene

I'm currently indexing a database with lucene. I was thinking of storing the table id in the index, but I can't find a way to retrieve the documents by that field. I guess some pseudo-code will further clarify the question:
document.add("_id", 7, Field.Index.UN_TOKENIZED, Field.Store.YES);
// How can I query the document with _id=7
// without getting the document with _id=17 or _id=71?
EDIT for Zend Lucene:
You will need a Keyword type field in order for it to be searched.
For indexing, use something like:
$doc->addField(Zend_Search_Lucene_Field::Keyword('_id', '7'));
For search, use:
$idTerm = new Zend_Search_Lucene_Index_Term('_id', '7');
$idQuery = new Zend_Search_Lucene_Search_Query_Term($idTerm);
Just to say I've just implemented this successfully on my Zend Lucene search engine. However, after some time troubleshooting I discovered that the field name and field value are the opposite way around to the way shown. To correct the example:
// Fine - no change here
$doc->addField(Zend_Search_Lucene_Field::Keyword('_id', '7'));
// Reversed order of parameters
$idTerm = new Zend_Search_Lucene_Index_Term('7', '_id',);
$idQuery = new Zend_Search_Lucene_Search_Query_Term($idTerm);
I hope that helps someone!

Categories