custom field search query problem
saul11
Joined: 2005-10-04
Posts: 109 |
Posted: Mon, 2007-04-23 13:03 |
I want to select items by specific custom field values. It seems to work almost, but just not the way it should: demo on http://www.saulmade.nl/gallery2/main.php?g2_view=customfieldsearch.CustomSearchScan (I'm fidling with the code so rubbish could be dumped on the screen and I could be switching between AND or OR) This is an 'AND search of custom field values' SELECT DISTINCT([CustomFieldMap::itemId]), [CustomFieldMap::field], [CustomFieldMap::value] FROM [CustomFieldMap], [GalleryAccessSubscriberMap] WHERE [CustomFieldMap::itemId] = [GalleryAccessSubscriberMap::itemId] AND(([CustomFieldMap::field] LIKE 'MediaType' AND [CustomFieldMap::value] LIKE 'Image') AND ([CustomFieldMap::field] LIKE 'Country' AND [CustomFieldMap::value] LIKE 'NL')) AND [GalleryAccessSubscriberMap::accessListId] IN (?,?,?,?) ORDER BY [CustomFieldMap::itemId] DESC testcase: mediatype=Image + Country=NL OR search of custom field values SELECT DISTINCT([CustomFieldMap::itemId]), [CustomFieldMap::field], [CustomFieldMap::value] FROM [CustomFieldMap], [GalleryAccessSubscriberMap] WHERE [CustomFieldMap::itemId] = [GalleryAccessSubscriberMap::itemId] AND(([CustomFieldMap::field] LIKE 'MediaType' AND [CustomFieldMap::value] LIKE 'Image') OR ([CustomFieldMap::field] LIKE 'Country' AND [CustomFieldMap::value] LIKE 'NL')) AND [GalleryAccessSubscriberMap::accessListId] IN (?,?,?,?) ORDER BY [CustomFieldMap::itemId] DESC testcase: mediatype=Image + Country=NL I believe I should do domething with a join, but I can't wrap my mind around it. Please help |
|
Posts: 1894
Hello,
I responded in the Channel but you seemed to have disappeared ...
The first query will never work and will return always null, this is because if this is true:
[CustomFieldMap::field] LIKE 'MediaType'
then this can't be true at the same time :[CustomFieldMap::field] LIKE 'Country'
The second query will work and will return duplicate rows because the returned record are not identical, putting a DISTINCT on the one column doesn't matter since there are 2 different record in the database and you really want both....
This will return only each ID once and that's all you need to get going:
If you need the CustomField Values for each of the entires, I suggest you do this after you have the correct itemIds returned
See you !
PS: Is this for iearn, if so, say hi from me ;-)
-------------------------
The Termite - - http://www.termitenshort.com/
Posts: 109
Hey Termite,
I saw in my logs that you tried to help me and I have sent you a note on the channel.
Thanks and thanks for coming here and help me again!
I do understand why it doesn't work, but getting it to work the way I want is something else
I had tried your suggestion before, but the problem with that query is that I can't do a AND search (several customfields must match) but only a OR search. I could do a seperate query for each custom field keyword and then intersect or merge or whatever the results, but I believe this shouldn't be that hard to do with a single query :-/
Hey it's indeed for iEARN, how do you know?! You don't happen to be 'Erfaan' do you?
Thanks,
Paul
Posts: 1894
Hello,
You can't do an AND search with this table it will never work. Indeed, if you're looking for an item that has both custom field, you need to do 2 queries. First query you get the result (Ids) of the custom field 1 and then you do another query with itemIds IN (x, x, x, x) and the second custom field.
You can also do a query within the query if you want, but it still truly 2 queries
I know it's for iEARN because I helped them out on other things and I didn't have the time to devote to look into this specific search
Hope this helps !
-------------------------
The Termite - - http://www.termitenshort.com/
Posts: 109
and when I have more custom fields?
a query per customfield?
Should you be able to work out a query using subqueries, please do
I believe I have made something working in the meantime. I will post it when it proves to be working after testing.
Thanks
Posts: 1894
Well the issue is with the way the database table is setup. there are colums itemId, Custom Field name & Custom Field value.
One thing you may be able to do is join that CustomField table twice on itself to search for 2 custom field for an item (that's pseudo code but you'll get the point) :
SELECT
TABLE1.itemId, TABLE1.Field, TABLE1.Value
FROM
(SELECT * FROM TABLE) TABLE1 inner join (SELECT * FROM TABLE) TABLE2 ON TABLE1.itemId = TABLE2.itemId
WHERE
TABLE1.field = 'Country' AND TABLE1.Value = 'NL' AND TABLE2.field = 'MediaType' AND TABLE2.value = 'Image'
This should in theory work perfectly and will only show the item from TABLE that have both these values for these respective custom field, you'll also have to add the AccessSubscriberMap to take into account the permissions but that should do it.
That's what I was refering too with the sub-queries. This will create tables on the fly of the same table and inner join them to only get the item that are on both tables respecting the condition you choose.
Ultimately, this is exactly the same as making 2 queries at once and may not work with older version of Mysql but with 5.x it works fine (I did a quick test and it's all good)
See you !
-------------------------
The Termite - - http://www.termitenshort.com/
Posts: 109
thanks, that was what I had in mind when I said 'I believe I should do domething with a join, but I can't wrap my mind around it.'...
I know subqueries don't work in older mySQL versions, but this is no subquery is it? I believe it's called a self join.
SO I have several options now:
- your query
- a query for each custom field
- a OR search with all custom field values and then when all custom fields should match, check on how many cutom fields for each result matched.
The query for the last option would be the 'OR search of custom field values' query in my initial post and would use this code to return all results on OR and only the items with all searched custom fields on AND. (Both results would hold all the custom field details that were found for each item.)
What would be the best (fastest) way to go?
Posts: 1894
The issue with option 3 is that you have a SQL query and then 2 php loop which render this a lot slower than just 1 query + 1 loop. Also you mentioned you may need more than 2 search item and then the "AND" part gets very complicated.
Option 2 was my first idea I guess but it will be slow (the slowest)
So I'd recommend option 1 (my query) for AND searches and option 3 (your OR query) for OR searches. This will probably achieve the best of breed fastest solution
See you !
-------------------------
The Termite - - http://www.termitenshort.com/
Posts: 5
How did you write that demo?