How do I do a boolean OR in solr? - php

I am completely new at this...
I am using durpal with the apachesolr module.
I have the following filter:
( tid:19895 OR tid:19937 ) AND type:poster"
This does not return any results, but if I have the following, it returns the results as expected
( tid:19937 ) AND type:poster"
EDIT: This is all in a filter. I need to have a list of tids that it could be along with having type be poster. So it has to be type:poster AND one of the following tids: 19895, 19937

although:
((tid:(19895 OR 19937)) AND type:poster) should work irrespective of defaultOperator being OR/AND
adding the clauses as separate filter is better, so add two filters as
tid:(19895 OR 19937)
type:poster
should filter out the results working as AND and also cache the results for this filter separately for improved query performance for new queries using this filter.

I think its important to note that SOLR isn't a database. Its a search engine and therefore isn't going to work like a database query you may be used to.
adding a + means the field is required
+tid:19895 would mean that TID field is required to equal exactly 19895
The * is the wildcard so adding it means your field would contain the value but not necessarily equal the value.
tid:19895* would mean TID field contains 19895
It looks like the issue is defining the field twice in the same filter???
So try removing the second "tid:"
In my testing I did this:
My SOLR query is:
+type:poster
And the Filter is:
tid:19895 OR 19937
Here is another stackoverflow question similar to yours since you obviously have a different syntax than I use.
using OR and NOT in solr query

As FYI if defalut boolen clause is "OR" then give the query like this
((tid:(19895 19937)) AND type:poster) This working fine i tested

Related

Search query containing a variable

HI I am working on a php mysql project and need some help.
On one of my fields I use a check box to enter a value. The possible options are 9001 14001 and 18001.
If I tick 14001 and 18001 the result that gets stored is 14001,18001.
When I set up a search I have had to set up an if equals for each possible combination. ..not too bad in this case as only 7.
Bit what would I use in an sql query if I wanted to say if (field) contains?
The following query would give you all line where field contains 14001.
SELECT * FROM table WHERE field LIKE '%14001%'
But you might want to reconsider the way you store your data to make it faster.
One way to do it is nicely described here:
http://www.phpknowhow.com/mysql/many-to-many-relationships/

Setting Boost in Solr - Adding conditions

I would like to know if there is a way / method to set conditional boosts
Ex:
if( category:1 )( field_1^1.5 field_2^1.2 )else if( category:3 )( field_3^7.5 field_4^5.2 )
I'm planning to set the "qf" and "pf" parameters this way in order to boost my results, is it possible?
Conceptually - yes, it could be done using function queries (http://wiki.apache.org/solr/FunctionQuery), it contains if function, but I wasn't able to do that by myself, since i couldn't use == operator.
Also, you could write your own function query.
But anyway right now it more looks like a good place to start, not concrete answer.
I think you have two ways of doing this...
First way, is by simplifying things at index time, so maybe create other set of redundant fields in the schema (ex: boostfield_1, boostfield_2, etc), and if the document category is 1, you can set the value of boostfield_1 to field_1, and boostfield_2 to field_2. But if category is 2, you can set it to other fields.
This will allow you to use "pf" straight away without having any conditions, as you already specified the conditions at index time, and indexed the document differently based on the category. The problem with that, is you won't be able to change the score of boost values of the fields according to the category, but it is a simpler way anyway
Use the _val_, or bq parameters to specify a boost query, and you can write the same query differently, so you can write the same condition as the following:
url?q=query AND _val_:"(category:1 AND (field_1:query OR field_2:query)) OR (category:3 AND field_2:query)"
The little problem here as well is you repeat the query text in every inner query, which is not a big deal anyway.

Exclude keywords from an empty query in Sphinx

Is it possible to exclude certain keywords from an empty query through Sphinx?
What I had in mind is to use the Extended2 match mode, and in order to exclude keywords, I'll be using the - or ! operator. I only need to fetch data through Sphinx without using any query (except for the exclusion operators).
In Sphinx, I fetch data using the following method:
$data = $sphinx->query('');
This query returns data which doesn't have to match anything (it means it'll return all data, and of course limited to the query limit). The problem is, if I add a keyword with the ! or - operator, it doesn't return anything. For instance:
$data = $sphinx->query('-google');
$data is returned as false
Maybe there is another method for this to work. Please help.
Thank you.
Sphinx doesnt like negation only queries. If you check GetLastError()/GetLastWarning() it will explicitly say so.
The main reason, is it can't efficently use its index. Sphinx is based on the concept of inverted indexes. So to run this query, it needs to fetch a list of every document, then remove the ones matching the keyword.
But you make it work. Just need to give sphinx a keyword that will be in every single document. Then can just do
$data = $sphinx->query('popularword -google');
If you dont have a word taht will be every document, just add a fake one :)
sql_query = SELECT id, '__ALL__' as dummy, title .......
can then just do
$data = $sphinx->query('__ALL__ -google');
As the word will be on every document.
Dont expect the query to be very fast.
As far as know it is not possible. Sphinx will fail at computing any query that involves searching through an entire collection.
For both options allowing you to use -, it is explicitly stated in the documentation that is is impossible:
SPH_MATCH_BOOLEAN:
Queries like "-dog", which implicitly include all documents from the collection, can not be evaluated.
SPH_MATCH_EXTENDED:
However, the query must be possible to compute without involving an implicit list of all documents
Short answer is: no, it is not possible. The only alternative is if you want to implement this for a small list of keywords, then you can add in your database a flag and set the value to true if the text contains this keyword. You'll be able to exclude them with a SetFilter() from your search results. I'm using this trick to exclude documents containing a certain set of keywords from my listings.

How do I include plurals but exclude singulars? [duplicate]

I am building a site with a requirement to include plural words but exclude singlular words, as well as include longer phrases but exclude shorter phrases found within it.
For example:
a search for "Breads" should return results with 'breads' within it, but not 'bread' or 'read'.
a search for "Paperback book" should return results with 'paperback book' within it, but not 'paperback' or 'book'.
The query I have tried is:
SELECT * FROM table WHERE (field LIKE '%breads%') AND (field NOT LIKE '%bread%')
...which clearly returned no results, even though there are records with 'breads' and 'bread' in it.
I understand why this query is failing (I'm telling it to both include and exclude the same strings) but I cannot think of the correct logic to apply to the code to get it working.
Searching for %breads% would NEVER return bread or read, as the 's' is a required character for the match. So just eliminate the and clause:
SELECT ... WHERE (field LIKE '%breads%')
SELECT ... WHERE (field LIKE '%paperback book%');
You should consider using FULL TEXT SEARCH.
This will solve your Bread/read issue.
I believe use of wildcards here isn't useful. Lets say you are using '%read%', now this would also return bread, breads etc, which is why I recommended Full Text Search
With MySQL you can use REGEXP instead of like which would give you better control over your query...
SELECT * FROM table WHERE field REGEXP '\s+read\s+'
That would at least enforce word boundaries around your query and gives you much better control over your matching - with the downside of a performance hit though.

Mysql - Simple select query returns duplicate values?

This is how the query looks like: (simplified)
SELECT * FROM posts WHERE user='37' ORDER BY date DESC
I currently only ave one row in that table, but still for some reason it returns two rows that are exactly the same. At first i thought i messed up with the loop, but i tried printing the returned array out with print_r() and it actually returns two rows.
I tried searching, but i didn't find any similar issues. I do however remember that a friend of mine had the same issue at school, so i'm sure we aint the only ones. I probably just didn't use the right search terms, heh.
If you have only one record (verify this), it has to be application logic that is duplicating the returned values.
Are you sure you only have one row in the table? If so, it seems like the problem must be happening outside of SQL.
What are you doing outside of this query? That seems like the likely source of the issue. You mention a loop: could you be adding the query result to your array twice? Or is the array persisting between calls without being reinitialized (in other words, the result of a previous query is remaining in the array when you don't expect it to)?
limit 1 is your friend :)
Try adding it to the end of your query.

Categories