find documents having no value for sql_attr_multi attribute (Sphinx) - php

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.

Related

How to create sql select by 3 level expression and statement

How to create sql select by 3 level expression and statement
Normally, my website based on SQLite database and the search result will be display by $sql =
"SELECT DISTINCT * FROM amz WHERE Title LIKE \"$qq%\" OR Price LIKE \"$qq%\" GROUP BY Title";.
Above will be search and select query that contains any search keyword from database in column Title or Price.
However, I need to create 3 expression and statement from database as:
Default will be search and display result as $sql = "SELECT DISTINCT * FROM amz WHERE Title LIKE \"$qq%\" OR Price LIKE \"$qq%\" GROUP BY Title";
If can't find any search result from Title and Price column. Then SQL will be check in Category column as $sql = "SELECT DISTINCT * FROM amz WHERE Category LIKE \"$qq%\" GROUP BY Title";
Finally, if not match in each column. SQL result will be echo custom message.
I try to create with myself. But it seems the result echo 1.) option only.
Example:
I search “bedding comforter set”. And in column Title in database had products contain this keyword without (s).
Initially, an expression will be check if it match 1). A statement will do selecting products from column Title or Price.
However, in column Category. I declare specific category to each product such as “bedding comforter sets” to Category.
So, if search not match bedding comforter sets in Title or Price. The result will be display products that match search query of bedding comforter sets in column Category instead Title or Price.
Finally, if not search query not match any in each column will be echo custom message.
Additional:
This is a screebshot comparing between query 1 and query 2 result
This screenshot is query 1 result that search keyword without (s) and like or match in Title column or Price column from database.
This screenshot is query 2 result that search keyword with (s) which like or match in Category column. This strange because it turns as Not Found while I set it to display result.
And this is my coding that I not sure it correct or not?
Thanks
Regards
Is there a requirement to write one sql to accomplish this?
You have essentially written pseudo-code:
Default will be search and display result as $sql = "SELECT DISTINCT * FROM amz WHERE Title LIKE \"$qq%\" OR Price LIKE \"$qq%\"
GROUP BY Title";
If can't find any search result from Title and Price column. Then SQL will be check in Category column as $sql = "SELECT DISTINCT * FROM
amz WHERE Category LIKE \"$qq%\" GROUP BY Title";
Finally, if not match in each column. SQL result will be echo custom message.
Now start expressing it in language the machine understands. A starting point:
execute and fetch result from query 1
if result set is not empty, display result
else execute and fetch result from query 2
if result set is not empty, display result
else display custom message
--EDIT --
Based on screenshot of code, you are not running the mentioned queries at all, but some other query modified by the str_repl. Which seems to morph it into an aggregate query (COUNT(*)), and aggregate queries always return at least one row. That could cause this problem.

Related Products SQL Query

I am trying to show something similar to related products on on my website. I have tested the following query, and I get no errors; but I get no results either.
<?php
$relatedStmt = $db->query("SELECT * FROM items WHERE tag LIKE id = 1 LIMIT 3");
?>
I also tried %1% and it displayed ALL the results, I assumed the code was thinking the query was just SELECT * FROM items.
The tags in the column are displayed in the following format: tagone two three four, so I am trying to display the products that have similar tags, hence why I used the LIKE clause.
Table screenshot
The current query is to relate with this query: SELECT * FROM items WHERE id = 1. So LIKE id = 1 is to find the tags that match this query to show the related products.
LIKE doesn't work the way you seem to expect. It's a character for character comparison, with wildcards, between the operands.
Of the mysql functions, closest to what you want is probably LOCATE or FIND_IN_SET. There are split solutions in other questions, e.g. "Can Mysql Split a column?" and "Split a MYSQL string from GROUP_CONCAT into an ( array, like, expression, list) that IN () can understand". However, even so there is no good way to compare the individual tags in your concatenated tag column with the individual tags of the other rows in your table.
Therefore, I think you'd be better off moving the tags into their own table with item_id as a foreign key. Then the solution is trivial (SQLFiddle):
-- Related Items
SELECT *
FROM items
WHERE id in (SELECT DISTINCT item_id
FROM tags t
JOIN (SELECT tag
FROM tags
WHERE item_id = 1
) t1 ON t1.tag = t.tag
WHERE item_id != 1
)
;
i am unsure about that id = 1 thing in your query but anyway you could try this: SELECT * FROM items WHERE tag LIKE '%search_this_tag%' LIMIT 3

Sphinx search sql_attr_multi - where condition

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.

Order a SQL Query by number of results

I want to do the following:
$searchParams is an array, which contains some strings (dynamicly generated).
Now the Statement would be something like this:
SELECT manufacturer FROM shop_articles WHERE manufacturer LIKE '".$searchParams."%'
But what I want is the result with the most matches. Can I code that in one statement?
So it would be something like
ORDER BY MATCHES DESC
How do I do that?
SELECT COUNT(*) AS matches, manufacturer FROM shop_articles WHERE manufacturer LIKE '".$searchParams."%' GROUP BY(manufaturer) ORDER BY matches ASC
For each param in your searchParam array you have to make a like clause
SELECT Manufacturer, COUNT(*) AS Matches FROM
FROM shop_articles WHERE (
manufacturer LIKE '".$searchParams[0]."%' OR
manufacturer LIKE '".$searchParams[1]."%' OR
...
manufacturer LIKE '".$searchParams[n]."%' OR )
GROUP BY Manufacturer
ORDER BY Matches
Actually you have to measure matching (likeness) between manufacturer and $searchParam. Unfortunatelly LIKE does not provide such functionality.
You may use Lavenshtein distances. See this post - Implementation of Levenshtein distance for mysql/fuzzy search?
SELECT manufacturer, COUNT(manufacturer) FROM shop_articles WHERE manufacturer LIKE '".$searchParams."' GROUP BY manufacturer ORDER BY COUNT(manufacturer) DESC
No, you cannot submit an array to the LIKE operator. It is more tedious than that. :-)
When your data are not yet properly regularized, so that you have variants of the manufacturer name in the PRODUCTS table (e.g. "HP", "Hewlett Packard") rather than an integer ManufacturerID, you have to go through the grunt work of reducing those variants to a single entity.
A typical approach for doing that (quite unavoidable) work is to create a Manufacturers table like this:
Table: MANUFACTURER
manufacturerid INTEGER primary key
manufacturername varchar
primarymanufacturerid INTEGER FOREIGN KEY REFERENCES MANUFACTURER(manufacturerid)
The last column allows you to associate a variant name (e.g. "HP") with the row where the main manufacturer record is stored (e.g. "Hewlett Packard").
124, Hewlett Packard, 124
367, HP, 124
The row where primarymanufacturerid = manufacturerid is the the main entity.
Then you could do this during an interim cleanup phase when you have not yet added a manufacturerid to the PRODUCTS table but it still has the name:
select * from products
where manufacturer in
(
select manufacturername from manufacturer
where primarymanufacturerid =
(
select primarymanufacturerid from manufacturer
where manufacturername = 'Hewlett Packard'
)
)
P.S. With a database engine that had support for functions and stored procedures, you could write your own function that accepted a delimited string of name variations, built a dynamic SQL statement, possibly using a temporary table to store the variant names one name per row, and returned a count of the matches. This would be a resource-intensive approach recommended only to assist in the clean-up phase -- not something I'd put into production for end-users to consume as their daily bread.
P.P.S. And, of course, once you have your MANUFACTURER table properly created, with the primarymanufacturerid references completed, you could add a [manufacturerid] column to your PRODUCTS table and update it accordingly, and then dispense with all of this roundabout stuff.
$sql = 'SELECT manufacturer FROM shop_articles WHERE 1=1';
for($i=0;$i
by this you can run query for $searchParams array dynamically

seo url`s in php

I have read about "slugs" but I still can`t figure out how to use them. How to properly save slugs in database ?
Lets say i have url like this http:/example.com/samsung/samsung_continuum_android_smartphone /
This is what I do
select category_id from categories where category_name = 'samsung'
After that I do query like
select slugs from my_table where category_id = (lets say 3 where is samsung)
Result is something like
samsung_continuum_android_smartphone
samsung_some_other_phone.
After that I can do something like this
select * from info where title = 'samsung_continuum_android_smartphone'
to get the information about the product. Is this the right way to do it ?
Your going a little over board, slugs are the exact same principle as unique identification numbers, the only difference is that a slug represents natural language for ease of reading as well as SEO.
Now I see that your performing 2 queries to get the row that matches the slug, where as you should only select 1 row from your info where the slug matches the container.
For instance:
SELECT * FROM categories WHERE category_slug = 'samsung';
the category_slug would be just as unique as category_id, thus removing any conflict's that may occur.
now if you construct your table scheme so that the slugs are only uniq to the category, this would remove conflicts but each slug for a post would need to be unique for the category, you can then select the correct post from the post table filtered by the category.
SELECT * FROM posts WHERE category_id = (SELECT category_id FROM categories WHERE category_slug = 'sumsung') AND WHERE post_slug = 'this_would_be_the_slug_for_the_post'
both of these values can be pulled from $_GET and placed into the above SQL String.

Categories