Use Boolean Operator(mini-language) in where clause - ruby-on-rails

I had implement SearchKick in my rails app. That app holds all the feature of searching that a recruiter app can have. I had working on this app for last 2 years and my searching query is written well enough to hold the aggregated data and some conditional clauses as well.
Now I want to implement "mini-language"(Boolean Operator) that is supported by elastic search using query_string.
Query String Supported Boolean Operator:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax
I want to use query_String with my existing SearchKick query. I know I can use Advanced Search but for this I would have to replace my current SearchKick query with an ElasticSearch query. I don't want to do that because it is a big change for my project which is live and has 1000+ of users.
I just want to adjust query_string in seachKick query in some way without having to replace it with ES query.
Is this possible?

I have the same problem.
But, if I understood the situation correctly, Searchkick maintainers decided to not support current behavior.
They mentioned it here:
https://github.com/ankane/searchkick/issues/97
and here:
https://github.com/ankane/searchkick/issues/1494
But, some workarounds may help you well enought.
You may do something like this:
Product.search body: {query: {query_string: {query: 'white shoes and water washable', default_field: 'product_description'}}}
I found it in this conversation:
https://github.com/ankane/searchkick/issues/1390#issuecomment-596657334
Or, you may just combine the needed fields into one for the search_data method. Which maybe even easier, but probably a more robust solution.
Please, see the reference below:
https://stackoverflow.com/a/51778715/2703618

Related

How to do partial search in rails?

I am trying to fetch all cards that do not belong to the current user and it's title contains some keywords.
What I have so far after research is this code below.
#other_cards = Card.where(:user_id.ne => #temp_current_user, "title LIKE ?" => "%Business%").limit(10).order('created_at desc down_title asc')
But there are no records being returned even thought they are present.
I have also tried to skip the :user_id condition and all the limits and orders, resulting in this simple code to check if it will return anything
#other_cards = Card.where("title LIKE ?", "%Business%")
EDIT
I have also tried putting the conditions as an array suggested in the first comment. It also resulted in a error
EDIT 2
Attaching screenshot of running the query in rails console
LIKE syntax is part of SQL. MongoDB, and Mongoid, do not (directly) support SQL. The general rule of thumb is Ruby methods carry over from ActiveRecord to Mongoid, for example the following works with both AR and Mongoid:
Card.where(id: 123)
... but once you start to specify complex conditions in either keys or values, they are often specific to the database you are working with. In the code you provided, the :user_id.ne syntax will not be recognized by ActiveRecord, and Mongoid/MongoDB do not recognize title LIKE ?.
Your problem statement was:
I am trying to fetch all cards that do not belong to the current user and its title contains some keywords.
MongoDB has native full text search capability, which is a superior solution to trying to match keywords with regular expressions or SQL LIKE operators. MongoDB has good documentation on full text searches here. The Ruby driver has further documentation, and examples, for how to use full text search here. Mongoid does not currently have documentation for full text search (there is an in progress pull request to add it here) but the gist of it is to combine the driver documentation referenced earlier with the documentation here for how to work with indexes in Mongoid in general.

How to implement fuzzy search

I'm using Neo4j 3 REST API and i have node named customer it has properties like name etc i need to get search results of name of customer eg i should get results for name "john" for my input "joan".how to implement fuzzy search to get my desired results.
Thanks in advance
First off, I want to make that you know that if you're using Neo4j 3.x that 3.x is currently in beta and isn't considered stable yet.
You have two options to implement a fuzzy search in Neo4j. You can use the legacy indexes to implement Lecene-based indexing. That should provide anything that Lucene can do, though you'd probably need to do a bit more work. You can also implement your own unmanaged extension which will allow you to use Lucene a bit more directly.
Perhaps the easier alternative is to use elasticsearch with Neo4j and have elasticsearch do your full-text indexing. You might take a look at the Neo4j and ElasticSearch page on neo4j.com. There they provide a link to a GitHub repository which is a plugin for Neo4j which automagically updates ElasticSearch with data from Neo4j and which provides and endpoint for querying your graph fuzzily. There is also a video tutorial on how to do this.
You will have to try using https://neo4j.com/developer/kb/how-to-perform-a-soundex-search/ which in this case will work. If your input is Joan you will not get John as the response, unless you just give jo as input in which you will get both. To get what you are expecting you will have to use the soundex search.
Stepping back a little, what is the problem you are trying to solve with fuzzy matching?
My experience has been that misspellings and typos are far less common than you might think, and humans prefer exact matches whenever possible. If there is no exact match (often just missing a space between words), that's a good time to use a spellchecker, and that's where the fuzzy matching should kick in.
In addition, your example would match "joan" to "john", but some synonyms like "joanie" would be more useful. If you have a big corpus of content to work with, you may be able to extract some relationships, using fuzzy & machine learning to identify "joanne" and "joni" as possible synonyms and then submit that to a human curator. "Jon" looks like a related name but it's not, while "jo" and even "nonie" may or may not be nicknames in these groupings.

What's the difference between “includes” and “preload” in an ActiveRecord query?

I'm struggling to find a comparison of includes() and preload() for ActiveRecord objects. Can anyone explain the difference ?
Rails has 2 ways of avoiding the n+1 problem. One involves creating a big join based query to pull in your associations, the other involves making a separate query per association.
When you do includes rails decides which strategy to use for you. It defaults to the separate query approach (preloading) unless it thinks you are using the columns from the associations in you conditions or order. Since that only works with the joins approach it uses that instead.
Rails' heuristics sometimes get it wrong or you may have a specific reason for preferring one approach over the other. preload ( and its companion method eager_load) allow you to specify which strategy you want rails to use.
As apidoc said "This method is deprecated or moved on the latest stable version. The last existing version (v3.0.9) is shown here." So the difference is that includes just NOT deprecated.

elasticsearch nGram/edgengram partial match?

I'm trying to make partial search working, a search for
"sw"
"swe"
"swed"
should match "Sweden"
I looked around and just can't get it to work
Rails Code
I'm using
this code from the Tire repo as templatecode.
whole words still match!
I have reindex and also tried using the edgengram filter.
I'm not a Ruby developper but found this article useful:
http://dev.af83.com/2012/01/19/autocomplete-with-tire.html
Like it sais:
Most databases handle that feature with a filter (with LIKE keyword in SQL, regular expression search with mongoDB). The strategy is simple: iterate on all results and keep only words which match the filter. This is brutal and hurts the hard drive. Elastic Search can do it too, with the prefix query.
With a small index, it plays well. For large indexes it will be more slow and painful.
You said:
whole words still match!
And what do you expect? Is "Sweden" not supposed to match "Sweden" but only "Swe", "Swed" or Swede" ?
Because your query on the field is also analyzed
Use the edgengram token filter. That will get you what you're looking for.

Thinking Sphinx Application Wide Search and Dealing with Results

The use case is this:
I'd like to let my user search from a single text box, then on the search results page organize the results by class, essentially.
So for example, say I have the following models configured for Thinking Sphinx: Post, Comment and User. (In my situation i have about 10 models but for clarity on StackOverflow I'm pretending there are only 3)
When i do a search similar to: ThinkingSphinx.search 'search term', :classes => [Post, Comment, User] I'm not sure the best way to iterate through the results and build out the sections of my page.
My first inclination is to do something like:
Execute the search
Iterate over the returned result set and do a result.is_a?(ClassType)
Based on the ClassType, add the item to 1 of 3 arrays -- #match_posts, #matching_comments, or #matching_users
Pass those 3 instance variables down to my view
Is there a better or more efficient way to do this?
Thank you!
I think it comes down to what's useful for people using your website. Does it make sense to have the same query run across all models? Then ThinkingSphinx.search is probably best, especially from a performance perspective.
That said, do you want to group search results by their respective classes? Then some sorting is necessary. Or are you separating each class's results, like a GitHub search? Then having separate collections may be worthwhile, like what you've already thought of.
At a most basic level, you could just return everything sorted by relevance instead of class, and then just render slightly different output depending on each result. A case statement may help with this - best to keep as much of the logic in helpers, and/or possibly partials?
If you have only 3 models to search from then why don't you use only model.search instead of ThinkingSphinx.search . This would resolve your problem of performing result.is_a?. That means easier treatment to the way you want to display results for each model.

Resources