How to do partial search in rails? - ruby-on-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.

Related

Use Boolean Operator(mini-language) in where clause

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

Rails Find Related Content

I'm trying to figure out a way to find related content on my Rails blog by utilizing the "name" field that I have. Is there any way to find closely related posts in the database based on similarity of the "name" field.
For example:
Post 1 name field = this-similarity-other-thing
and
Post 2 name field = this-similarity-something-else
Is there any way I can search and find "this-similarity" as being roughly the same in the string, thus being able to pull it from the database and allow it to be shown in the view as related content?
I'm not sure exactly what you're looking for in Rails, but this is how I would do it in SQL:
SELECT b.name
FROM blogs b
WHERE b.name LIKE 'this-similarity-%'
Perhaps the Rails syntax would be something like:
Post.where("name ILIKE 'this-similarity%'")
Of course, how you get the context of the post you're currently (what I hard-coded as 'this-similarity%') on will depend on your implementation details.
if you want to just match on a substring, you can use a wildcard
Post.where("name LIKE '%substring%'")
if you want to incorporate something more flexible, you can try to get more advanced with ransack and elasticsearch
Use SIMILAR TO instead of LIKE - it allows to work with regular expressions
names = ['first', 'second', 'third'].join('|') # it gives "first|second|third" string
similar = Post.where("name SIMILAR TO '%(#{names})%'")

Rails Active Record Relation sorting

Let's say I have a ruby on rails model, with a text field. Let's say I also have a query string. I want to make a query that sorts the database in descending order of maximal number of overlapping characters between the text field and the query string. How would I go about this?
Probably you can go with LIKE SQL statement, but will not be efficient.
Here is an example:
Company.where(Company.arel_table[:name].matches("%stack%"))
If you need to make a lot of queries search the text inside a field in database, you really need to start looking for a full text search software.
I can recommend you Elastic Search, unless you are familiar with some other tool.
You have here a recent tutorial and also a Railscast on subject.

Is it possible to alias or rename fields in YQL?

I'm making a bunch of YQL queries at once & have a standard way of accessing the fields on the server. Unfortunately one of the feeds uses a different name than the rest for a field so I was assuming I could alias it within YQL.
Something like:
SELECT title, link, encoded AS description FROM...
But it looks like YQL's parser doesn't like that as I get this error:
Syntax error(s) [line 1:37 expecting field got 'AS']
So, is it possible to alias fields in YQL like you can in SQL? I don't seen anything in the YQL docs or on the internet at large.
Tacking another (small) question on as well, is there a spec anywhere for YQL's syntax?
No, it's not possible to do an alias in the YQL query. (As #codeulike mentioned, it's really not true "SQL" like you might find in MySQL or other databases.)
One capability that might help your needs is the ability in Open Tables to create an alias for parameter names. See the YQL Open Tables documentation and search for "alias".
I think YQL corresponds to SQL in only a metaphorical sort of way; although it superficially uses things like SELECT, it doesn't try to cover much of the breadth of SQL. Hence if its not in the documentation, its probably not possible.
In this guide: http://developer.yahoo.com/yql/guide/select_statement.html ... aliasing of fields is not mentioned, so I figure its not a feature.
Although, if you run your YQL query through Yahoo Pipes, you can use their Rename module to rename elements of the data.

Using Ferret to build unique tag clouds

I've been using Ferret as my full-text search engine in a small project I'm working on.
Through the documentation and a few examples online, i've been able to pull together a tag cloud generator using the full-text index to help with tag cloud generation using the IndexReader.terms method.
It's worked quite well up to now, when I want to get term data based on a search result.
For example, if the user searches for "cake", I want to show them a tag cloud of terms used in association with the term "cake".
I've been looking for examples of where the terms method can be used in association with a search result set or similar?
Currently I'm using the following method to generate my list of tags:
reader = Ferret::Index::IndexReader.new(Scrape.find_last_index_version)
terms = []
reader.terms(:all_quotes).each do |term, doc_freq|
terms << [term, doc_freq]
end
Cheers.
It's more like a term frequency chart (like a wordle) than a tag cloud? Or are these in a tag field? Anyway, the index doesn't keep track of term frequency within each possible document subset (such as the results of a search), so that method wouldn't be fast, even if it existed. For a single document, you can get the TermFreqVector and provide suggested documents that are good matches for other frequent terms in that document. So, you could take some of the top results, grab the term vectors from each one, and just add them up, but those aggregate functions don't exist natively (they generally try not to put slow operations in there.)

Resources