Yii2 hide filter input action in pretty Url - url-rewriting

Hi please help how can i change the url in Yii2 as below, the input values are from form inputs to filter user input value.
https://mywebsite/listing/search?select1=Kuala+Lumpur&select2=Private+Room&keyword=Suasana&select3=4&select4=4
to
https://mywebsite/listing/search/Kuala+Lumpur/Private+Room/Suasana/4/4
I tried below code, but it's not working
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'listing/search/<select1>/<select2>/<keyword>/<select3>/<select4>' => 'listing/search',
'landlord' => 'site/landlord'
],
],

You need to let the UrlManager know the patterns that the parameters should match and the ones that they shouldn't.
Looking at the example that you provide:
search?select1=Kuala+Lumpur&select2=Private+Room&keyword=Suasana&select3=4&select4=4
It seems like you want to match anything to select1 and select2, you could use . to match any character and + to match one or more occurrences:
.+
It looks like you only want letters for keyword:
\w+
If you also wanted to match digits:
[\w\d]+
If you only want to match digits for select3 and select4:
\d+
Remove the + if you only want to match a maximum of one digit.
The UrlManager configuration would look like this:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'listing/search/<select1:.+>/<select2:.+>/<keyword:\w+>/<select3:\d+>/<select4:\d+>' => 'listing/search',
'landlord' => 'site/landlord'
],
],
If you want to experiment with different regex patterns without having to reload the page, I find regexr is fantastic.
The Yii2 docs themselves have a good section on the topic.

Related

Elasticsearch Completion Suggester ignores Index parameter and returns results for multiple indices

I'm using the PHP implementation of Elastic to use a Completion Suggester like this:
$params_organisations = [
'index' => $this->organisation_index,
'body' => [
"suggest" => [
"suggestions" => [
'prefix' => $request->q,
"completion" => [
"field" => "suggest1",
"fuzzy" => ["fuzziness" => 0],
"skip_duplicates" => "false",
"size" => 7
]
]
]
]
];
However, the response contains other indices as well:
suggest: {suggestions: Array(1)}
timed_out: false
took: 8
_shards:
failed: 3
failures: Array(3)
0:
index: ".kibana_1"
node: "xxxxxxxxx"
reason: {type: "illegal_argument_exception", reason: "no mapping found for field [suggest1]"}
I fear this might impact performance as some other indices do contain a suggest1, field as well and they are searched and returning results. I've not changed the names and sometimes I want to treat the suggest fields in a similar way, but is it problematic to have identical suggest-type field_names across indices?
Or is there a way to more explicitly define an index? I've also tried appending the index name to the endpoint, but same result. I've found an explicit suggest endpoint in the PHP implementation, but it seems to be deprecated? Any help is much appreciated!
Ok, so the problem was not with ElasticSearch, it turns out the index string coming from the configuration was not being processed correctly, yielding an empty string, causing Elastic to query all indices.

How to count most occurring word from a set of documents then perform sub aggregations

From an Elasticsearch query, I am able to produce let's say around 5000 documents
Now, I'm trying to determine which non-stop words (stop words are auxiliary verbs / non-significant words) are appearing the most.
So I tried this query using the significant_text aggregation
$params2 = [
'index' => ["web", "print"],
'type' => 'index',
'from' => 0,
'size' => 10000,
'filter_path' => ['aggregations'],
'body' => [
"query" => //omitted query here
'aggs' => [
'SIGNIFICANT' => [
"significant_text" => [
"field" => "content"
]
]
]
]
];
Unfortunately, it still displays some garbage words that are not significant to me
My Questions:
1. Is there an alternative for significant_text aggregation?
I also want to perform a terms sub-aggregation after this significant_text main aggs, because I want to combine a query to know the popular words, and then filter the documents according to the other fields
Would greatly appreciate it if you have an idea how to perform this desired process and output

Exclude white space from Elasticsearch when searching

I've got elastic search working great on my site, I can search pretty descent. My problem is when i do a search on something like HipHop vs Hip Hop, or cellphone vs cell phone, my results for the first text query won't appear . I want to make it so that if a user searches either word with or without a space, the results will be the same. here's what my code to search looks like. I'm using Laravel 5
$q = $request->input('q');
$response = $client->search([
'index' => 'users',
'type' => 'user',
'body' => [
'query' => [
'bool' => [
'should' => [
['match' => [ 'text' => $q ] ],
],
],
],
],
]);
First you must understand the index process, basically your string is passed trough the default analyser if you didn't change the default mapping.
HipHop will kept the same
Hip Hop is saved separated like Hip, Hop
When you do a match query like your example with HipHop vs Hip Hop, this query is passed trough the analyser too and will be separated like: "HipHop, vs, Hip, Hop" and a boolean query that will do a search like this: "match HipHop there?", "match vs there?", "match Hip there?", "match Hop there?" ?
If you want a scenario where you have HipHop indexed and the user search for Hip Hop or HipHop vs Hip Hop or HopHip and should return HipHop, you must implement some strategy like:
Regex or prefix query: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html
Ngram for partial matching: https://www.elastic.co/guide/en/elasticsearch/guide/current/_ngrams_for_partial_matching.html
Synonyms: https://www.elastic.co/guide/en/elasticsearch/guide/current/using-synonyms.html
And if you want to keep you terms with space indexed like "Hip Hop" you need to use a not_analyzed mapping.

Elasticsearch autosuggest

a newbie to ES needs helping hands for the Suggester....
I made a simple index with some titles like "Manufacturer product name mpn":
My current Mapping:
'suggest'=> [
'=> 'completion'
'=> 'simple'
' => false
]
my current Query:
'body' => [
'suggest' => [
'text' => $this->query
, 'completion' => [
'field' => 'suggest'
]]]
Now if I try to Suggest it works, but results are very ugly....
Perhaps somebody can help me to find the right settings:
e.g. a title is: "Xoar Electric Beechwood Precision"
Now i want this results for Queries:
"X" => "Xoar"
"Yoar E" => "Xoar", "Xoar Electric"
"El" => "Electric"
"Elektric " => "Electric", "Electric Beechwood"
At the moment it only returns the full title if I type "X...."
Is this possible?
And if yes, how can i try to get this results?
THANKS in advance!
You need to change default tokenizer and analyzer to fetch related documents from elasticsearch.
Check below links for more details which talks about how to handle human language and typo corrections,
Human Languages with elasticsearch
Fuzzy matching with elasticsearch
You should use ngrams approach i.e. tokenize your words by splitting them with space character or what suits your use case the most. Then index each token with the suggest analyzer.
For ex:
Split "Xoar Electric Beechwood Precision" like this
"Xoar Electric Beechwood Precision"
"Electric Beechwood Precision"
"Beechwood Precision"
"Precision"
And then use the prefix query. For auto-correcting, you may use fuzziness parameter.
Hope this helps.

Retrieving a Subset of Fields from MongoDB in Ruby

I'm trying to get a subset of fields from MongoDB with a query made in Ruby but it doesn't seem to work. It doesn't return any results
This is the ruby code:
coll.find("title" => 'Halo', :fields => ["title", "isrc"]) #this doesn't work
If I remove the fields hash, it works, returning the results with all the fields
coll.find("title" => 'Halo') #this works
Looking at the mongodb console the first query ends-up on the mongodb server like this:
{ title: "Halo", fields: [ "title", "isrc" ] }
If I try to make the query from the mongo client console, it works, I get the results and the subset. I make the query like this:
db.tracks.find({title: 'Halo'}, {title:1,isrc:1})
What could be the problem? I've been looking for a solution for this for a couple of hours now.
As of Sep, 2015, these other answers are outdated. You need to use the projection method: #projection(hash)
coll.find({"title" => 'Halo'}).projection({title: 1, isrc: 1})
The query should look like
collection.find(selector = {}, opts = {})
Query the database
In your case it is
coll.find({"title" => 'Halo'}, {:fields => ["title", "isrc"]})
But still remains a problem, the ruby-driver ignores the condition of "fields", and returns all the fields! :\
This query will return only the title and isrc for a doc that has the title "Halo":
coll.find({"title" => 'Halo'},{:fields => {"_id" => 0, "title" => 1, "isrc" => 1}})
Note the use of a Hash for the fields where the keys are the field names and the values are either 1 or 0, depending on whether you want to include or exclude the given field.
You can use the below query
coll.find({"title" => 'Halo'}).projection({title: 1, isrc: 1, _id: 0})
if you don't want _id, to be retrieved in case.

Resources