Sphinx search sql_attr_multi - where condition - php

I need to set an index.
sql_attr_multi = uint categories from query; SELECT item_id, category_id FROM connections WHERE value=2
It works fine If I set the value static.
That value is a variable so I want to assign it through a filter but it doesn`t work because I want to filter "sql_attr_multi" not the $sql.
$cl->setFilter("value", array(2));
Thanks

setFilter has to do only with searching ( searchd process ). It's a filter applied to an attribute.
The categories sql_attr_multi attribute values can't be changed depending on a condition ( unless you reindex or use updateAttributes).
If values doesn't vary much , create for each one a mva attribute.

Related

mySQL query to get only display

I wanted to ask one question as my query skills are not that great and I have been learning mySQL for the last week. This attachment I have shows what happens when I run the following query:
SELECT * FROM clothing, sizing WHERE id = "101";
You might notice that it produces the same id number, same name, same type, same brand_id,same price, and a lot of null values. Is there a query which I can run which only displays columns which do not have null values?
You can select the rows that dont have null values in given columns, or you can use IFNULL.
IFNULL(yourColumn,0)
This will display 0 instead of Null, but beware that NULL and 0 is not the same thing.
Null is "nothing" / undefined, 0 is a numerical value.
You can have issues multiplying with NULL, so you can do for instance:
SELECT (numProducts * IFNULL(productPrice,0))
FROM ...
You can also use CASE or IF to select differenct colums and alias them :-)
External link to docs: https://dev.mysql.com/doc/refman/4.1/en/control-flow-functions.html
Yes above solutions will work only if that column has default value set to null,if its not set then you need to check blank ,i mean to say IFNULL(productPrice,0) will not work you need to do as below,
SELECT (numProducts * IF(productPrice='',0,productPrice))
FROM ...
You are basically asking about two problems that I will address separately in this answer.
1 - More than one record is returned
You should follow mathielo and Olavxxx's comments regarding the use of JOIN.
The query as shown in your question is a cartesian product between your tables clothing and sizing. What the query is basically asking is "I want only the record with id 101 in one of the table, as well as all the records in the other table".
Judging by the rest of your question, this is not what you want. So I take it there is a relationship between rows in clothing and sizing. I will assume that a clothing can only have one size, and that this relationship is represented by a foreign key to sizing. Here the minimum the tables should contain for that to work (I do not reuse your model because from the details in the question I can only guess, not know, what your exact table model is):
clothing:
id: primary key
size_id: foreign key to sizing
sizing:
size_id: primary key
As a consequence, the following query should return all records corresponding to the selected clothing and associated size:
SELECT *
FROM clothing AS c
JOIN sizing AS s ON c.size_id = s.size_id
WHERE c.id = 101
Your relationship between your two tables may actually be different from what I have just modeled. If that is the case, I still hope the above example is enough to get you started in the right direction.
2 - Lots of NULL values
This part of the question needs to be precised. Is it that you do not want the records with NULL values for some columns to be returned, or is it that you just do not want to get the content of these columns? Or maybe you want to use a default value?
If it is the records you want to filter out, you should add <column> IS NOT NULL conditions in your WHERE clause. One for each of the columns you are interested in.
If it is the columns you do not want to get, do not use SELECT * but instead explicitely list the columns you want, for example:
SELECT id, name, price FROM clothing
If it is about using a default value instead, you need to use IF in the SELECT clause as in Supriya's answer. Another example:
SELECT name, size, IF(shoulder IS NULL, 'Default', shoulder)
FROM clothing

Search by serialized value

This is the query i use for getting the data out of my database
SELECT
product_description.name as name,
product.image as iurl
FROM
product_description, product
WHERE
product_description.product_id = product.product_id
AND product.product_id
AND product.product_id = '33';
Why is this query producing double results?
I want to automaticly search by multiple values (id's) stored in database instead of manually adding the AND product.product_id='?' part. Values are stored in serialized form.
something like
... AND product.product_id in (setting.value WHERE key='featured');
I know that query is not correct, just trying to show what i want.
table 'setting':
value | key
-------------------
23,43,28 | featured
Solution
To get the details of all products which are stored in your settings table (comma separated) you can use FIND_IN_SET()
SELECT
product_description.description,
product.name,
product.id
FROM
product_description, product
WHERE
product_description.id = product.id
AND FIND_IN_SET(product.id, ( SELECT value FROM setting where `key` = 'featured' ) );
SQLFiddle
Note: The reason why you see duplicated entries could be because there are multiple descrioptions for a particular product, you can handle this using GROUP_CONCAT
The following should work
Epilogue
Your database design is not good, It should be something like
product -- All my products go here
product_details -- Details of all the products ( A product could have multiple details)
categories -- eg: Featured, Seasonal
product_categories -- association of product to categories
This is somehow breaking the relational paradigm, you should have three entries with values 23, 43 and 28.
Then again I'm guessing field value is a varchar (do you know "value" and "key" are reserved words by mysql ?) so you might want to look inside the string to find pattern ",23," inside the field. Something like : WHERE CONCAT(',', field_value, ',') LIKE "%,23,%"

How could I go by storing items from my database into an array, but only if that item is not already in the array?

I need to grab categories name from my database and store them into an array, but I don't want to grab the same category twice. Is there a way to, once I grab the category name and store it into an array to skip that category and not store it any more?
SELECT DISTINCT categoryname FROM CategoryTable
How about using DISTINCT in your original query?
http://www.mysqlfaqs.net/mysql-faqs/SQL-Statements/Select-Statement/How-does-DISTINCT-work-in-MySQL
If DISTINCT doesn't work for you (maybe you have multiple queries...), you should use your array as a set. Use this to add to the array:
arr[$category] = true;
In MySQL, if I understand your question:
select distinct `category` from table;

Find Rows in Vertical Line-separated values in MySQl?

Let say i have a field 'category' with the value '1|2|3'. I want to search in mysql such that it will return all rows matching my search parameter into the values of the category.
for example:
$cat_id = 1;
SELECT * FROM `myTable` WHERE cat_id is equal or found in category with values '1|2|3'...
something like that..i do not know how to put it in correct sql query.
Any Ideas? thanks in advance.
Well you could manage it using the MySQL-specific regex operator:
WHERE category RLIKE '(\\||^)'+cat_id+'(\\||$)'
(Assuming MySQL non-standard backslash escapes are enabled, which they are by default.)
However, this kind of query is not indexable and it's generally considered extremely poor schema design to fudge multiple datapoints into one column like that. The usual solution is a join table of myTable to category.
this must be a table "category", not field.
SELECT * from mytable, cattable, where cattable.id=1 and cattable.mid=mytable.id

find documents having no value for sql_attr_multi attribute (Sphinx)

in my sphinx source config I have an attribute like so:
sql_attr_multi = uint categories from query; SELECT entry_id, cat_id FROM categories_entries
When querying the sphinx index, is it possible to get only records that do not have a category attribute? As a kludgy fix I have executed a query on the database to find all potential category ids and then excluded those attributes from the Sphinx results:
$query = $DB->query("SELECT GROUP_CONCAT(cat_id SEPARATOR ',') AS categories
FROM categories WHERE category_group='3'
GROUP BY category_group");
$sphinxclient->SetFilter("categories", explode(",", $query->result[0]['categories']), true);
This works but it seems like there should be a better way.
There's no way to check if an MVA collection is empty for a given document... however, you could add another integer attribute which is the COUNT for categories attached to each document. Then you can filter on that equalling zero, or being within a certain range.

Categories