Use * (asterix) as a term query in Elastic search - php

I have a document with a tag '*'
Yet when I construct a term query it returns no results. How can I query documents with the tag '*'. My guess is it's a special character that needs to be escaped.
Update with answer
I needed to set the property to not analyzed so that elastic search wouldn't strip out punctuation etc.
$myTypeMapping = array(
'_source' => array(
'enabled' => true
),
'properties' => array(
'tag' => array("type" => "string", "index" => "not_analyzed")
)
);
$indexParams['body']['mappings']['file'] = $myTypeMapping;

If your tag field is analyzed then the the star is not indexed. See for yourself:
curl -XGET 'localhost:9200/_analyze?analyzer=standard' -d '*'
Response:
{"tokens":[]}
You will need to change the field to not_analyzed or to change the analyzer.

Related

Algolia filtering not working

I have a search index with the following settings:
$index->setSettings([
'searchableAttributes' => ['title', 'datePublished'],
'attributesForFacetting' => ['filterOnly(tags)']
]);
I add objects to the index like so:
$index->addObject([
'objectID' => $object->getId(),
'title' => $object->getTitle(),
'tags' => $object->getTags(), // i.e. ['tag one (special)', 'tag two', 'tag three']
'datePublished' => $object->getDatePublished()->getTimestamp()
]);
I then conduct a search to get related items like so:
$index->search(
[
'filters' => $tags, // i.e. "tags:tag one (special)" OR "tags:tag two"
'hitsPerPage' => 12
]
);
However, this always returns 0 results, even though there are multiple records with the tags being searched for. I verified this in the Algolia dashboard. So what am I doing wrong here and how do I fix this?
Everything you're doing seems to be correct. The only issue is coming from the way you are escaping the filters in the final search() call.
Your $tags variable should be {"filters": "tags:'tag one (special)' OR tags:'tag two'"}.
The filters key should always be a string, with each filter delimited by OR/AND. When the value is a single word, you don't need any quotes, but if it has several words, you need to enclose them in '.

How to append or replace document field in elastic search php?

I am trying to write update query which replace or append field content
$params = [
'index' => 'products',
'type' => 'product',
'id' => '57b31c5c04736da90a91bc2b',
'body' => [
'script' => 'ctx._source.product_content_changes = ctx._source.product_content)',
]
];
$result =$client->update($params);
My requirement is to replace or append content in product_content field.
For example
product_content => This Is Test Text i want to replace Test to Changed so new field will contain this text This Is Changed Text.
In mysql this query will be something like this
update products set product_content_changes = replace(product_content,'Test','Changed') where id="57b31c5c04736da90a91bc2b";
Thanks

Elasticsearch exact match field

I have a field called url that is set to not_analyzed when I index it:
'url' => [
'type' => 'string',
'index' => 'not_analyzed'
]
Here is my method to determine if a URL already exists in the index:
public function urlExists($index, $type, $url) {
$params = [
'index' => $index,
'type' => $type,
'body' => [
'query' => [
'match' => [
'url' => $url
]
]
]
];
$results = $this->client->count($params);
return ($results['count'] > 0);
}
This seems to work fine however I can't be 100% sure this is the correct way to find an exact match, as reading the docs another way to do the search is with the params like:
$params = [
'index' => $index,
'type' => $type,
'body' => [
'query' => [
'filtered' => [
'filter' => [
'term' => [
'url' => $url
]
]
]
]
]
];
My question is would either params work the same way for a not_analyzed field?
The second query is the right approach. term level queries/filters should be used for exact match. Biggest advantage is caching. Elasticsearch uses bitset for this and you will get quicker response time with subsequent calls.
From the Docs
Exclude as many document as you can with a filter, then query just the
documents that remain.
Also if you observe your output, you will find that _score of every document is 1 as scoring is not applied to filters, same goes for highlighting but with match query you will see different _score. Again From the Docs
Keep in mind that once you wrap a query as a filter, it loses query
features like highlighting and scoring because these are not features
supported by filters.
Your first query uses match which is basically used for analyzed fields e.g when you want both Google and google to match all your documents containing google(case insensitive) match queries are used.
Hope this helps!!

Filter query: Not null in elastic search

Currently I am working on Elastic Search 2.0 for my current Project. MySqL Query As follows,
select user_id from users where subscription_type ! = ''
In This above query, I Need to write in Elastic Search, I am trying in elastic search but it getting
please find below code in elastic search
$query = array("from" => $start,
"size" => $recordslimit,
"sort" => array(array('id' => 'desc')),
"query" => array(
"filtered" => array(
"query" => array("match_all" => array()),
"filter" => array("bool" => array(
'must_not' => array(
array('term' => array('subscription_type' => ''))
)))
)));
please help me out with this situation
I see two possible scenarios:
If subscription type is null or doesn't appear in your documents, then you can use missing query instead of a term query in the must_not clause.
On the other hand if you would like to exclude those documents whose subscription_type field holds the empty string, then your query is correct but maybe your mapping isn't. Make sure that subscription_type is defined as not_analyzed in the mapping.

How to update/replace a field in an ElasticSearch document using PHP?

I want to update my Elasticsearch indexed document's field. In my case its the tags field.
This is the code I currently have:
// Index tags in the page document
$es_client->update([
'index' => 'myappname',
'type' => 'page',
'id' => $page_id,
'body' => [
'doc' => [
'tags' => $tagsArray
]
]
]);
So, this would update my document by adding the tags array to it, but it won't remove the old tags.
How can I make sure that the old tags get removed when I add the new tags?
I did look in the documentation, but as we all know, the Elasticsearch docs can be very confusing and all-over-the-place. Hence I am asking here after days of searching.
Any help or advice would be greatly appreciated.
Standard update behavior is to merge array/object fields as explained in the update API documentation .
...objects are merged together, existing scalar fields are overwritten
and new fields are added.
So instead you would use a script to modify the document source directly. You can make it generic and thus cacheable, and pass in params for better performance. Php API documentation
// Index tags in the page document
$es_client->update([
'index' => 'myappname',
'type' => 'page',
'id' => $page_id,
'body' => [
'script' => 'ctx._source.tags=tags',
'params' => ['tags' => $tagsArray]
]
]);

Categories