Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiple where conditions and concatenated with AND #48

Open
danieldias51 opened this issue Jul 15, 2019 · 3 comments
Open

multiple where conditions and concatenated with AND #48

danieldias51 opened this issue Jul 15, 2019 · 3 comments

Comments

@danieldias51
Copy link
Contributor

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.

@mrkamel
Copy link
Owner

mrkamel commented Jul 15, 2019

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.

@danieldias51
Copy link
Contributor Author

So any tips where I should start looking? Can you give me a little brief where and how this interpretation is being handled?

@mrkamel
Copy link
Owner

mrkamel commented Jul 15, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants