support ranges and boolean term condition in searchkick rails 5? - searchkick

I'm using Searchkick in my Rails 5 application and I'm trying to support ranges and boolean term condition in app.
My range query with where like:
Model.search '*', where: { _or: [ { age_years: { gte: "5", lte: "7" } } ] }
But I got an error as below:
"caused_by":{"type":"illegal_argument_exception","reason":"Cannot search on field [age_years] since it is not indexed."}
Also I've tried with aggs query like:
options = {:aggs=>{:age_years=>{:ranges=>[{:from=>7, :to=> 12}]}}} Model.search("*", options)
But I got an error as below:
{"type":"illegal_argument_exception","reason":"Fielddata is disabled on text fields by default. Set fielddata=true on [age_years] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."}
My term query like:
Model.search "*", where: {lc_vet_care: true}
But I got not indexed error same like range where query error.
how can I fix this with searchkick?

Related

(Boolean logic) What is a workaround for duplicate keys when working with boolean logic in MongoDB?

When I'm trying to query for several categories in a database, such as:
Example: {
"AttributeA": type,
"AttributeB": type,
"AttributeC": type,
"AttributeD": type
etc...
}
And say that I'm trying to query for samples that have (AttributeA matching criteria1 or AttributeB matching criteria2) and (AttributeC matching criteria3, 4, 5, or 6). How would we compose the .find() method in MongoDB to match without error or complicated boolean algebra (distributing out the "and")?
I've tried using notation such as:
db.Example.find({
$or:[{"AttributeA" : criteria1, "AttributeB" : criteria2}],
$or:[{"AttributeC" : criteria3, "AttributeC" : criteria4, ...}]
})
in an attempt for an easy query satisfying the conditions above, but in some cases this would result in only one condition of the query being satisfied (giving a "duplicate key '$or'" warning before compiling) and in other instances (different platforms) this straight up gives an error along the lines of the warning.
If I understood the question correctly, I think you are looking for a query predicate such as:
{
$or: [
{
AttributeA: "criteria1"
},
{
AttributeB: "criteria2"
}
],
AttributeC: {
$in: [
"criteria3",
"criteria4",
"criteria5"
]
}
}
See how it works on this playground example
How would we compose the .find() method in MongoDB to match without ... complicated boolean algebra (distributing out the "and")?
By default, MongoDB applies an implicit $and operator to query predicates at the same level. There is an explicit operator also available, but it is not needed in your situation. You can allow the database to distribute the condition(s) that is logically $anded for you.
AttributeC matching criteria3, 4, 5, or 6
This is a perfect use for the $in operator, which I've used in the query above as:
AttributeC: {
$in: [ "criteria3", "criteria4", "criteria5" ]
}

MongoDB Atlas - Boost search score from external list of words

I use MongoDB Atlas' full-text search which can boost the search score (how relevant a result is for that particular search query) by specifying the path that should be weighed more. Example:
text: {
query: query,
path: ["title"],
allowAnalyzedField: true,
score: { boost: { value: 2 } },
}
This will give results where the query appears in the "title" property a higher weight.
I want to do the same, but instead of specifying a path, I want to check if the query appears in an array of strings that I prepare beforehand. I want to weigh these words/phrases higher. How can I do that?

Elasticsearch high level rest client more than 1 field search

I am using Scala 2.12 to query the ElasticSearch (6.5).
I am able to use querybuilders for a single field search like below:
val searchSourceBuilder = new SearchSourceBuilder()
val qb = new BoolQueryBuilder()
.must(QueryBuilders.regexpQuery("header.fieldname", "01_.+_20190711_data"))
searchSourceBuilder.query(qb)
Using the above (I need regex search) I can search the relevant documents.
However, I have more complex requirement, where I have to match the documents on more than one field-value pair.
i.e.
header.fieldname should match pattern "01_.+data"
AND
header.fieldname2 should match pattern "type.+_2019-07-11"
Basically, it is like SQL where clause on 2 or more columns (and value string).
I was checking https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
But this is like searching the same string (value) in multiple fields. This is NOT what I want.
I basically want something like SQL AND in where clause (better if it is with regex too).
UPDATE:
Please note the below answer by #Meet Rathod works and accepted.
However, to take it forward, so if I need one more condition which is SQL OR, is my below code correct.
Required:
header.fieldname: 01_.+data AND header.fieldname2: type.+_2019-07-11 AND (header.fieldname3: some_thing OR header.fieldname3: some_other_thing)
Code:
val qb = new BoolQueryBuilder()
.must(QueryBuilders.regexpQuery("header.fieldname", "01_.+_20190711_data"))
.must(QueryBuilders.regexpQuery("header.fieldname2", "type.+_2019-07-11"))
.should(QueryBuilders.regexpQuery("header.fieldname3", "some_thing"))
.should(QueryBuilders.regexpQuery("header.fieldname3", "some_other_thing"))
Is this correct or I am missing something?
As far as I understand, you want only those document which satisfies all your conditions should list out in the result. And if that's the case I believe adding another must clause in your query should get your expected result. The raw query will look something like this.
{
"query": {
"bool": {
"must": [
{
"regexp": {
"header.fieldname": "01_.+data"
}
},
{
"regexp": {
"header.fieldname2": "type.+_2019-07-11"
}
}
]
}
}
}
I'm not sure but, your Scala code should look something like this.
val qb = new BoolQueryBuilder()
.must(QueryBuilders.regexpQuery("header.fieldname", "01_.+_20190711_data"))
.must(QueryBuilders.regexpQuery("header.fieldname2", "type.+_2019-07-11"))

Build Query based on Conditions [duplicate]

I am working on a nodejs/express app with Mongodb on the backend. In one of my API calls, depending on the presence of a particular querystring parameter or the other I want to issue a query to Mongodb with either a $gt or a $lt.
In some cases we want to ask for everything less than the tokenId using $lt, but in other cases we want everything greater than the tokenId using $gt. How do we do that without duplicating the queries?
Here's an example query:
collection.find({'film_id': {$in : genre}, '_id': {$lt: tokenId}}).sort({'_id': -1}).limit(25).toArray(function(error, films)
Is there a way to dynamically create the query without actually doing 2 different queries?
Build up your query object programmatically:
var query = {'film_id': {$in : genre}};
if (param) {
query._id = {$lt: tokenId};
} else {
query._id = {$gt: tokenId};
}
collection.find(query).sort({'_id': -1}).limit(25).toArray(function(error, films);
Update
Now that Node.js 4+ supports computed property names, you can create query in one step as:
var query = {
film_id: {$in: genre},
_id: {[param ? '$lt' : '$gt']: tokenId}
};
The Above code may not work. The above dynamic query will be resolved to following Ex. Token is an integer 35.
collection.find("_id":"{$gt: 35}")
.sort({'_id': -1}).limit(25).toArray(function(error, films);
resulting in Error
The correct syntax should be:
collection.find("_id":{$gt: 35}).
The double "" quotes should not be there.

How to filter minimongo collection with more parameters in meteor

I need help with filtering reactively minimongo collection with 3+ parameters. Firs, I have loaded minimongo from server's mongo collection with publish/subscribe. Now, I want to filter that collection and let user see only objects from collection that are same like filters. First of all I have search query filter that checks if input string is same as some filed in collection:
Job.find({ $or: [ { Name: regex }, { Description: regex }, ]});
This part is doing his job well. And now second filter: I have field in object that is true if that particular job is remote friendly and false if it is not, I wanted to if user enables that filter he only see just remote friendly job positions, and if he disables that, he can see all jobs available ( + search query of course):
if (remoteQuery === true ) {
return Job.find({ $or: [ { Name: regex }, { Description: regex }, ] , Remote: true});
}
This is working, but it is bad way for doing this. And now biggest problem comes with last filter: I have one more field that is storing "job" (collection object) type. Type can be 1, 2 , 3 or 4. So how could I say to minimongo e.g. "Show only jobs that have "Front-end" inside (search query), that are remote friendly, and have third filter 2 and 3 inside"
Job.find({ $or: [ { Name: "Front-end"}, { Description: "Front-end"}, ] , Remote: true, positionType: [2,3],});
Something like this? Thanks!
Sounds like you are looking for the MongoDB query $in operator:
The $in operator selects the documents where the value of a field equals any value in the specified array.
Therefore your 3rd query could look like:
Job.find({
positionType: {
$in: [2, 3] // Matches documents where `positionType` is either 2 or 3
},
// Other conditions…
});