Problem/Motivation
It would be useful to be able to perform a full text search in a conditionGroup, but currently, that is not supported.
Proposed resolution
Pass the query settings (which includes fuzziness) from QueryParamBuilder (where the data is available) to FilterBuilder.
Add a LIKE operator to the supported query conditions, which runs an Elasticsearch match query on the condition's field, with the given search-term-value and query's fuzziness (or the default fuzziness if not specified).
Add a NOT LIKE operator to the supported query conditions, which wraps an Elasticsearch must_not boolean query around a match query on the condition's field, with the given search-term-value and query's fuzziness (or the default fuzziness if not specified).
Adds an EXACT operator to the supported query conditions, which runs an Elasticsearch match_phrase query on the condition's field with the given search-term-value.
Remaining tasks
Write a merge request- patch by @artemboiko in #2; converted to merge request !52 by @mparker17 in #4Review and feedback- reviewed by @mparker17 in #22 and @fathershawn in #30 and #31RTBC and feedbackCommit to 9.0.x- committed by @mparker17 in #33Commit to 8.0.x- committed by @mparker17 in #35Release 9.0.x- released in 9.0.0-alpha3 by @mparker17Release 8.0.x- released in 8.0.0-alpha7 by @mparker17
User interface changes
None.
API changes
Adds arguments to FilterBuilder::buildFilters() and FilterBuilder::buildFilterTerm() (both public functions) but provide default values, so this is still backwards compatible.
Data model changes
None.
Original report by @artemboiko
Added LIKE and EXACT elastic operator like in parent issue but for 8.0.x-dev
If possible, it would be nice to have a NOT LIKE filter too
The parent issue says...
I was trying to create a custom query on Elastic and I needed to perform a full text search in a conditionGroup and the keys() method cannot support that.
To do that I've made two additional filters on FiltersFactory.php, LIKE, and EXACT to query the elasticsearch server with a full text.
Not sure if it's the best method, I'd love some feedback on this.
| Comment | File | Size | Author |
|---|
Issue fork elasticsearch_connector-3444888
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
artemboikoComment #5
mparker17@artemboiko, thank you! (and apologies: I only have expertise in the 8.0.x branch of the module, so I'm unable to help move the 8.x-7.x branch forward!)
I've created a merge request: lets see if tests pass.
Offhand, the code looks fine thus far. May I request that you update the test at
tests/src/Unit/SearchAPI/Query/FilterBuilderTest.phpto test the new code? (this will ensure that future changes don't accidentally break the LIKE and EXACT functionality you need!)Thank you very much!
Comment #6
mparker17If possible, it would be nice to have a NOT LIKE filter too, as put forward in #3092486-10: LIKE filter missing. That issue (which is a lot older and uses the old, switch-based syntax) suggests the following code...
... I'd like to close that other issue in favor of this one, so I'm pasting it here so that the code isn't forgotten.
Comment #8
mparker17Crediting @abrar_arshad because they proposed a patch in #3092486: LIKE filter missing
Comment #10
mparker17Crediting @artemboiko because they were not credited automatically
Also crediting @sokru because they provided direction in #3092486: LIKE filter missing
Comment #12
mparker17Crediting @kevinn because they proposed a patch in #3092486: LIKE filter missing
Comment #13
mparker17Assigning to myself to see if I can integrate the NOT LIKE filter, and add some tests.
Going to rebase onto the latest 8.0.x
Comment #14
mparker17That seemed to work!
Although that being said, our tests (currently) only test that the queries get constructed in the way we expect, i.e.: we don't (yet) test that Elasticsearch 8 can parse them or that they return results that make sense for that kind of query.
I noticed that both the
LIKEandNOT LIKEfilters in #3092486: LIKE filter missing both specifywildcardqueries, but theLIKEfilter from this issue does not. However, I copied theNOT LIKEquery construction from #3092486: LIKE filter missing for now.We don't seem to use
wildcardqueries anywhere else in the 8.0.x version of this module. Our sibling project, Search API OpenSearch doesn't either (or at least, not in their 3.x branch).I'm not exactly certain why we aren't using
wildcardqueries, but I daresay for now we should try to be internally consistent, i.e.: change theNOT LIKEquery I just added fromwildcardto something else; but I'm not particularly familiar with raw Elasticsearch query construction, so I'm not certain if — for example — changingwildcardtotermwould work without manual testing (which I will try shortly).Comment #16
mparker17Crediting @karma86 for the patch in #3268303: LIKE and EXACT filter for searching fulltext (8.x-7.x) (for this module's 8.x-7.x branch)
Comment #17
mparker17Should probably add #3092486: LIKE filter missing as a related issue too, even though it's been closed as a duplicate of this one.
Comment #18
mparker17I grepped the code in Search API, and a number of modules providing search backends for it to see if I could find any other examples of
LIKEand/orNOT LIKEfilters... the only match was insearch_api'ssearch_api_dbsubmodule (i.e.: an SQL-based search backend), which implementedLIKEandNOT LIKEby escaping any%and_wildcard characters in the search term, then performing an SQLLIKE '%term%'query.That says to me that end-users shouldn't be able to enter raw wildcards, meaning that we shouldn't be creating a
wildcardquery in our implementation. (but maybe I misread, please correct me if I am wrong). From a security perspective, I can imagine that allowing end-users to enter wildcards directly means that malicious end-users could create wildcard-filled queries to slow down the back-end, potentially causing problems for other users. But, I don't know if Elasticsearch has some built-in guardrails to prevent that.It is also worth noting that all of our other filter term operators create
termqueries (which look for exact matches). However, @artemboiko's implementation forLIKEin #2 creates amatchquery (which fuzzy-matches the search term instead of looking for an exact match). Fuzzy-matching is not the same thing as an SQLLIKE '%term%', but I daresay that @artemboiko's implementation feels like the right solution here... it seems to me thatLIKEshould be more lenient than=; andNOT LIKEseems as if it should be more lenient than<>... and while we could implementLIKEandNOT LIKEexactly likesearch_api_dbdoes, it seems to me like one of the reasons why someone might want to use ElasicSearch instead of SQL is because ElasticSearch has fuzzy-matching and SQL does not.However, if you have a good counter-point, I'd be interested to hear it!
Acting on the above thoughts, I have left the
LIKEimplementation the way that @artemboiko wrote it, and changed theNOT LIKEimplementation to avoid creating a wildcard query...I think this is ready for review now, but since I worked on the patch, I cannot RTBC it anymore. So I'll unassign myself, and leave this as "Needs review" for others to provide feedback.
Thank you in advance! (and sorry for the long comment)
Comment #19
sokru commentedLooks good to me, only thing I was wondering that we hardcode the fuzziness value here to "auto" and someone might expect to get the setting from here: https://git.drupalcode.org/project/elasticsearch_connector/-/blob/8.0.x/...
Comment #20
mparker17@sokru, good idea, I'll update the merge request!
Comment #21
mparker17Ready for re-review!
Comment #22
mparker17Briefly checking the status of this issue after releasing 8.0.0-alpha5...
Comment #23
mparker17I've updated the issue summary as best I can.
(going to remove one of the tags that has recently become "undefined" — I don't remember what it was though)
Comment #24
mparker17(update the issue title to distinguish this from #3268303: LIKE and EXACT filter for searching fulltext (8.x-7.x))
Comment #25
mparker17Re-reviewing this after a bit of time, it looks like I addressed @sokru's concern in #19. I'm also happy again with my code, so I'm rebasing onto the latest 8.0.x.
If tests pass, I'll create a branch to 9.0.x so we can review/merge there first.
Comment #26
mparker17Tests pass; changing version to 9.0.x then creating a branch.
Comment #30
fathershawnMR181 is RTBC
Comment #31
fathershawnReading through MR51, it looks the same. No surprise as these two branches have not diverged much. Also RTBC
Comment #32
mparker17Awesome, thanks for the review @fathershawn! Merging!
Comment #34
mparker17Merged to 9.0.x; will merge to 8.0.x shortly.
Comment #36
mparker17Merged to 8.0.x as well. I'll update this issue when this change is released. Thanks everyone!
Comment #39
mparker17The changes in this issue were released in elasticsearch_connector-9.0.0-alpha3, and elasticsearch_connector-8.0.0-alpha7