search_cop
search_cop copied to clipboard
multiple where conditions and concatenated with AND
Hi,
I'm using search_cop to perform a full text search on two models with a relationship, but the way WHERE
condition is generated is not allowing me to get any results.
The scenario:
I've a model lets call it A
and it has a one to many relation with a model B
.
This model B
is a table with synonyms, so it just has a "synonym" and the foreign key for the model A.
I've created on the model A
a grouped FTS key attributes all: [:name, :description, ...]
and on the model B
I've just one field with FTS key.
My problem, the query generated has 2 "MATCH AGAINST" conditions, one for the first grouped key and one for the other key, exactly as it should, but they are concatenated by an AND
then:
WHERE
((MATCH(`A`.`name`, `A`.`description`, `A`.etc...) AGAINST('+my +search' IN BOOLEAN MODE)))
AND
((MATCH(`B`.`name`) AGAINST('+my +search' IN BOOLEAN MODE)))
Since the second table is a synonym table, if it doesn't match the search it prevents me from getting results...
Is there a way to use OR
instead of an AND
to concatenate the conditions?
If not, I'd be glad to contribute if you want.
I'm facing also other issue, the +
added before each term.
This make the term required, so if the user type a word without a match, the hole query doesn't return results.
Is there an option to prevent to add the +
?
I'd be glad to create a PR to add those features if you want. I would only need some tips from you.
Hi, thx for your feedback.
So, in essence you ask for what elasticsearch calls the "default_operator": https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
Currently, search_cop always uses AND as default operator, such that if you search for "term1 term2", search_cop interpretes it as "term1 AND term2", but you want it to interprete it as "term1 OR term2" by default. It should be possible to add this feature and i'm open for a PR.
Your second point should be "fixed" via the default_operator option as well.
So any tips where I should start looking? Can you give me a little brief where and how this interpretation is being handled?
Sure, it starts in the treetop grammer.
More specifically, in rule and_expression
spaces are interpreted as AND operators.
We need to change <AndExpression>
within
... / space !('OR' / 'or')) complex_expression <AndExpression> / ...
to
<AndOrExpression>
and add
class AndOrExpression
def evaluate
[elements.first.evaluate, elements.last.evaluate].inject(query_info....default_operator)
end
end
in search_cop_grammer.rb
, while the default_operator
needs to be passed through via the query_info
object.