How use full text TNTSearch facade - php

I tried TNTSearch, but the results are only for the complete words. For example, the phrase Facilis dolorem gives me all combinations of records with the word facilis or word dolorem.
How can I do to the search with TNTSearch in Laravel?
LIKE %lore%
If I type lore, I don't get the records that have the word lore in the middle.

You should enable fuzzy search via config like mentioned in the docs:
'tntsearch' => [
'storage' => storage_path(), //place where the index files will be stored
'fuzziness' => env('TNTSEARCH_FUZZINESS', false),
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
],
ie. if this is your config set you variable TNTSEARCH_FUZZINESS in .env to true and you should get the results you expect.
Also, if you already have indexes created which seems like you do you'll have to reindex the content in order for fuzzines to kick in...

mine same issue not solved and finally used other good alternate:
laravel-scout-mysql-driver
try it
but exactly answer for your question:
you must use *lore* in your query. more documentation for queries:
Boolean Full-Text Searches

I had this issue and solved it via add 'asYouType' => false, in config\scout.php.
my code is :
'tntsearch' => [
'storage' => storage_path(), //place where the index files will be stored
'fuzziness' => true,
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
'asYouType' => false,
],

Related

Laravel 8 update JSON column value

I'm trying to update the value of a json column type for all of my users, my query that I'm running through Tinker doesn't give any errors, it just returns 0 and the columns remain unchanged, what am I doing wrong?
User::where('notification_preferences')->update(['notification_preferences' => [
'domains' => [
'expiry' => [
'mail' => true,
'database' => true
]
]
]])
My columns on my rows currently has the value of...
{
"expiry_alerts": true
}
After I have read the comment below it came clear to me that you used the wrong syntax for the WHERE query of a JSON column. You have to use the -> operator.
For further information please see https://mattstauffer.com/blog/new-json-column-where-and-update-syntax-in-laravel-5-3/
&
https://laravel.com/docs/8.x/queries#json-where-clauses
It should work like this:
User::where('notification_preferences->expiry-alerts',true)->update(['notification_preferences' => [
'domains' => [
'expiry' => [
'mail' => true,
'database' => true
]
]
]])
I think the problem is your where clause User::where('notification_preferences'), if you express this to sql User::where('notification_preferences')->toSql(), you will notice something like this
from users where notification_preferences is null..., probably this is the reason why the update is not executed.

How can I fetch results from elastic search from one column with different values at the same time?

I am using REST API using PHP for fetching data from Elastic search with following code
$params = [
'index' => $search_index,
'type' => $search_type,
'from' => $_POST["from"],
'size' => $_POST["fetch"],
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'is_validated' => false ] ],
[ 'query_string' => [ 'query' => $search_str, 'default_operator' => 'OR' ] ]
]
]
]
]
];
Now, this is working perfectly and giving me my desired results.
The data that is returned from ES, has one column "result_source" and it has predefined values like CNN, BBC or YouTube etc.
What I need is, I want to filter results on "result_source" column in a way that, I can only fetch the results with the option I want. Like I want results that have "result_source" value only "YouTube" or only "BBC & CNN" or only "CNN or YouTube" etc.
I have already tried "Should" option, but it also returns the data with other values that I don't need. Not sure how to skip those values of "result_source" column in fetching results from ES.
Any help on this will be appreciated.
Thanks
Solved!!
I am replying to my own question, because I found a solution for it. May be it can help someone else in future.
If anyone is looking for a solution of searching within the field / column of Elastic search, here is what can be done.
[ 'query_string' => [ 'query' => $search_str.'(result_source:CNN OR result_source:BBC)', 'default_operator' => 'OR' ] ]
"result_source" is actually the field / column name of ES on which filter is applied to return results that have result_source=BBC or result_source=CNN.
This actually solved my issue.

How can I fetch distinct records from Elasticsearch

I am working on Elasticsearch (ES) for last couple of weeks. There are millions of records currently present in different search indices in ES.
I have noticed that in different search indices, there is duplication of records and it is creating problem.
We can search for duplicate records via code and remove those records. May be this can be applicable, but I have more than 100 million records so it will take lot of time.
My requirement is, while we fetch records from ES, we can apply different filters. Is there any filter or way we can only fetch distinct records? I am currently using REST API using PHP.
Here is the code that I am currently using and filters are working perfectly.
$params = [
'index' => 'MyIndex',
'type' => 'MyType',
'from' => 0,
'size' => 10,
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'image' => true ] ],
[ 'simple_query_string' => [ 'query' => 'MyQuery' ] ]
]
]
]
]
];
I also tried looking something from "Aggregations", but couldn't find something related to my requirement.
Quick help will be highly appreciated.
Thanks in advance.
I think what you are looking for is "collapsing".
Elasticsearch supports it from 6.x:
https://www.elastic.co/guide/en/elasticsearch/reference/6.x/search-request-collapse.html

Creating campaign for dynamic TextMerge segment fails

I'm trying to send a campaign to a dynamic list segment based on a custom numeric merge field (GMT_OFFSET, in this case) but the code below yields the following error from the MailChimp API:
"errors" => [
0 => [
"field" => "recipients.segment_opts.conditions.item:0"
"message" => "Data did not match any of the schemas described in anyOf."
]
]
My code, using drewm/mailchimp-api 2.4:
$campaign = $mc->post('campaigns', [
'recipients' => [
'list_id' => config('services.mailchimp.list_id'),
'segment_opts' => [
'conditions' => [
[
'condition_type' => 'TextMerge',
'field' => 'GMT_OFFSET',
'op' => 'is',
'value' => 2,
],
],
'match' => 'all',
],
],
],
// Cut for brevity
];
If I am to take the field description literally (see below), the TextMerge condition type only works on merge0 or EMAIL fields, which is ridiculous considering the Segment Type title says it is a "Text or Number Merge Field Segment". However, other people have reported the condition does work when applied exclusively to the EMAIL field. (API Reference)
I found this issue posted but unresolved on both DrewM's git repo (here) and SO (here) from January 2017. Hoping somebody has figured this out by now, or found a way around it.
Solved it! I passed an integer value which seemed to make sense given that my GMT_OFFSET merge field was of a Number type. MailChimp support said this probably caused the error and suggested I send a string instead. Works like a charm now.

elasticsearch sort data in fuzzy mode

I want to sort data by more similar in elasticsearch with fuzzy mode
we have to record
1.panadol
2.penadol
when I search with panadol or penadol the first result is (penadol) but I want wen I type (panadol) the first result appear (panadol) and the second result id (penadol) etc ..
$params = [
'index' => 'my_index',
'type' => 'my_type',
'body' => [
"track_scores"=> true,
'sort'=>[
'name'=> ['reverse'=>true],
'_score'=> ['order'=>'desc'],
],
'query' => [
'fuzzy' => [
'name' => [
"value"=> 'panadol',
"fuzziness" => 2,
]
]
],
]
];
Fuzziness is not meant for scoring. You can find more info about it in the docs.
If you want to sort the results by relevance to the original phrase your searched for you can use either the phrase-suggester or the completion-suggester, depending on your needs (and your data).

Categories