I am trying to achieve a filter in Sphinx so that I can filter out the results from two MVA attributes (what I need is a double condition, but since MVA is only 2 fields..) from the same joined table, but whatever I do, It seems that I keep getting the same results since there is always a match on the first field in the multi attribute?
Maybe there's another solutions but I can't seem to find out how to get my desired result, I got to simplify 4 tables: PRODUCT, CATEGORY, PRICE and POSITION.
Data set-up
Below a sample of the data structure:
PRODUCT
+------+-------------+-----------------+---------------+
| ID | CATEGORY_ID | MANUFACTURER_ID | TITLE |
+------+-------------+-----------------+---------------+
| 1000 | 1000 | 1000 | Apple iPhone |
| 1001 | 1000 | 1000 | Apple iPad |
| 1002 | 1000 | 1000 | Apple iPod |
| 1003 | 1001 | 1001 | Do not show |
+------+-------------+-----------------+---------------+
CATEGORY
+------+-------+
| ID | TITLE |
+------+-------+
| 1000 | Apple |
| 1001 | Other |
+------+-------+
PRICE
+------+--------+---------+
| ID | USERID | PRICE |
+------+--------+---------+
| 1000 | 1000 | 359.00 |
| 1001 | 1001 | 1058.30 |
| 1002 | 1002 | 1078.00 |
| 1003 | 1003 | 1160.45 |
| 1004 | 1004 | 1180.00 |
| 1005 | 1000 | 1190.00 |
| 1006 | 1000 | 228.76 |
+------+--------+---------+
POSITION
+------+------------+--------+------+
| ID | PRODUCT_ID | USERID | RANK |
+------+------------+--------+------+
| 1000 | 1000 | 1000 | 1 |
| 1001 | 1001 | 1001 | 1 |
| 1002 | 1001 | 1002 | 2 |
| 1003 | 1001 | 1003 | 3 |
| 1004 | 1001 | 1004 | 4 |
| 1005 | 1001 | 1000 | 5 |
| 1006 | 1002 | 1000 | 1 |
+------+------------+--------+------+
Sphinx Set-up:
source product
{
type = mysql
sql_host = localhost
sql_user = ...
sql_pass = ...
sql_db = ...
sql_query_pre = SET NAMES utf8
sql_query = SELECT P.ID AS ID, C.ID AS SEARCH_CAT_ID, P.CATEGORY_ID, P.MANUFACTURER_ID, P.TITLE AS TITLE_SORT FROM CATEGORY C, PRODUCT P WHERE P.CATEGORY_ID=C.ID
sql_attr_uint = CATEGORY_ID
sql_attr_uint = MANUFACTURER_ID
sql_attr_string = TITLE_SORT
sql_attr_multi = uint POS_RANK from query; SELECT PRODUCT_ID, RANK FROM POSITION
sql_attr_multi = uint POS_USERID from query; SELECT PRODUCT_ID, USERID FROM POSITION
}
index product
{
source = product
path = ...
docinfo = extern
min_word_len = 1
}
MySQL Dump:
CREATE TABLE IF NOT EXISTS `CATEGORY` (
`ID` int(11) NOT NULL,
`TITLE` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `CATEGORY` (`ID`, `TITLE`) VALUES
(1000, 'Apple'),
(1001, 'Other');
CREATE TABLE IF NOT EXISTS `POSITION` (
`ID` int(11) NOT NULL,
`PRODUCT_ID` int(11) NOT NULL,
`USERID` int(11) NOT NULL,
`RANK` int(11) NOT NULL,
PRIMARY KEY (`ID`),
KEY `USERID` (`USERID`),
KEY `PRODUCT_ID` (`PRODUCT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `POSITION` (`ID`, `PRODUCT_ID`, `USERID`, `RANK`) VALUES
(1000, 1000, 1000, 1),
(1001, 1001, 1001, 1),
(1002, 1001, 1002, 2),
(1003, 1001, 1003, 3),
(1004, 1001, 1004, 4),
(1005, 1001, 1000, 5),
(1006, 1002, 1000, 1);
CREATE TABLE IF NOT EXISTS `PRICE` (
`ID` int(11) NOT NULL,
`USERID` int(11) NOT NULL,
`PRICE` decimal(9,2) NOT NULL,
PRIMARY KEY (`ID`),
KEY `USERID` (`USERID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `PRICE` (`ID`, `USERID`, `PRICE`) VALUES
(1000, 1000, '359.00'),
(1001, 1001, '1058.30'),
(1002, 1002, '1078.00'),
(1003, 1003, '1160.45'),
(1004, 1004, '1180.00'),
(1005, 1000, '1190.00'),
(1006, 1000, '228.76');
CREATE TABLE IF NOT EXISTS `PRODUCT` (
`ID` int(11) NOT NULL,
`CATEGORY_ID` int(11) NOT NULL,
`MANUFACTURER_ID` int(11) NOT NULL,
`TITLE` varchar(255) NOT NULL,
PRIMARY KEY (`ID`),
KEY `CATEGORY_ID` (`CATEGORY_ID`),
KEY `MANUFACTURER_ID` (`MANUFACTURER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `PRODUCT` (`ID`, `CATEGORY_ID`, `MANUFACTURER_ID`, `TITLE`) VALUES
(1000, 1000, 1000, 'Apple iPhone'),
(1001, 1000, 1000, 'Apple iPad'),
(1002, 1000, 1000, 'Apple iPod'),
(1003, 1001, 1001, 'Do not show');
ALTER TABLE `POSITION`
ADD CONSTRAINT `POSITION_ibfk_1` FOREIGN KEY (`PRODUCT_ID`) REFERENCES `POSITION` (`ID`) ON DELETE CASCADE;
ALTER TABLE `PRODUCT`
ADD CONSTRAINT `PRODUCT_ibfk_1` FOREIGN KEY (`CATEGORY_ID`) REFERENCES `CATEGORY` (`ID`) ON DELETE CASCADE;
Test 1
SphinxQL Query for filter USERID:
SELECT ID FROM product WHERE MATCH('1000') AND POS_USERID IN (1000) ORDER BY WEIGHT() DESC LIMIT 0,20 FACET POS_RANK LIMIT 5;
Result for USERID (first set seems OK this time, second returns everything):
+------+
| id |
+------+
| 1000 |
| 1001 |
| 1002 |
+------+
+----------+----------+
| pos_rank | count(*) |
+----------+----------+
| 5 | 1 |
| 4 | 1 |
| 3 | 1 |
| 2 | 1 |
| 1 | 3 |
+----------+----------+
What I expected:
- Product ID (1000,1001,1002)
- Position Rank (1 with count 3, 5 with count 1)
Test 2
SphinxQL Query for filter USERID 1000 and RANK 5:
SELECT ID FROM product WHERE MATCH('1000') AND POS_USERID IN (1000) AND POS_RANK IN (5) ORDER BY WEIGHT() DESC LIMIT 0,20 FACET POS_RANK LIMIT 5;
Result for USERID and RANK (first set seems OK this time, second returns everything):
+------+
| id |
+------+
| 1001 |
+------+
+----------+----------+
| pos_rank | count(*) |
+----------+----------+
| 5 | 1 |
| 4 | 1 |
| 3 | 1 |
| 2 | 1 |
| 1 | 1 |
+----------+----------+
What I expected:
- Product ID (1001)
- Position Rank (5 with count 1)
Test 3
SphinxQL Query for filter USERID 1000 and RANK 4:
SELECT ID FROM product WHERE MATCH('1000') AND POS_USERID IN (1000) AND POS_RANK IN (4) ORDER BY WEIGHT() DESC LIMIT 0,20 FACET POS_RANK LIMIT 5;
Result for USERID and RANK (first stil returns product, second returns everything):
+------+
| id |
+------+
| 1001 |
+------+
+----------+----------+
| pos_rank | count(*) |
+----------+----------+
| 5 | 1 |
| 4 | 1 |
| 3 | 1 |
| 2 | 1 |
| 1 | 1 |
+----------+----------+
What I expected:
- Product ID (empty set)
- Position Rank (empty set)
I hope you guys understand what I am trying to achieve and can help me out?