Elastisearch Failed to JSON encode issue - php

I working on elastic search and I have 1K phone numbers when I pass this phone numbers array to elastic search to search users through phone numbers it gives me exception
Failed to JSON encode /var/app/current/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Serializers/SmartSerializer.php
Below is my Elasticsearch client initializing
$client = ClientBuilder::create()->setHosts([$host])->build();
And my working query in Elasticsearch
{
"_source": [
"id"
],
"query": {
"bool": {
"must": [
{
"term": {
"type": "user"
}
},
{
"bool": {
"should": [
{
"prefix": {
"phone": {
"value": "923047698099"
}
}
},
{
"prefix": {
"phone": {
"value": "92313730320"
}
}
},
.
.
.
]
}
}
],
"must_not": [
{
"has_child": {
"type": "blocked",
"query": {
"term": {
"user_id": "u-2"
}
}
}
},
{
"has_child": {
"type": "block",
"query": {
"term": {
"user_id": "u-2"
}
}
}
},
{
"term": {
"db_id": 2
}
}
]
}
}
}
I don't know that where I doing mistake. Either at client initializing or writing elasticserch query. I searched this issue but not usefull solution found or might be I did't understand clearly. But still I am stucked on this issue that how to solve this problem. Suggest any usefull link or solution.
Thanks

Related

Delete document older than One hour is not working in elasticsearch

I am new to elasticsearch and I have an document in elasticsearch and document contain thosands of user views and now I want to delete those view that are older than 3Hours for this purpose I write following query in elasticsearch
POST {INDEX}/_delete_by_query
{
"query": {
"bool": {
"must": [
{
"term": {
"type": "box_views"
}
},
{
"query": {
"range": {
"#created_at": {
"gte": "now-3h"
}
}
}
}
]
}
}
}
When I execute this query I receive following error
{ "error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "no [query] registered for [query]",
"line": 1,
"col": 66
}
],
"type": "parsing_exception",
"reason": "no [query] registered for [query]",
"line": 1,
"col": 66 }, "status": 400 }
Your query should look like this:
POST {INDEX}/_delete_by_query
{
"query": {
"bool": {
"must": [
{
"term": {
"type": "box_views"
}
},
{
"range": {
"#created_at": {
"gte": "now-3h"
}
}
}
]
}
}
}
Besides, if you're looking for older documents, I think you should use lte instead of gte.

How to calculate average minimal times in Elasticsearch?

Use Elasticsearch version is 5.4.2
I'd like to build an Elasticsearch query to satisfy three conditions.
filter by championId
get minimal time to buy various item per game
calculate avg minimal time to buy each item in all games.
I did 1 and 2. But I could not find solving 3. Is it possible to execute 1 to 3 in the query? Just in case, I will use the result on Laravel 5.4, one of PHP frameworks.
My data format is the following:
"_index": "timelines",
"_type": "timeline"
"_source": {
"gameId": 152735348,
"participantId": 3,
"championId": 35,
"role": "NONE",
"lane": "JUNGLE",
"win": 1,
"itemId": 1036,
"timestamp": 571200
}
My current Elasticsearch query is this
GET timelines/_search?size=0&pretty
{
"query": {
"bool": {
"must": [
{ "match": { "championId": 22 }}
]
}
},
"aggs": {
"games": {
"terms": {
"field": "gameId"
},
"aggs": {
"items": {
"terms": {
"field": "itemId",
"order" : { "min_buying_time" : "asc" }
},
"aggs": {
"min_buying_time": {
"min": {
"field": "timestamp"
}
}
}
}
}
}
}
}
As #Sönke Liebau said pipeline aggregation is the key, but if you want to count average minimal time of all games per item you should first aggregate by itemID. Following code should help:
POST misko/_search
{
"query": {
"bool": {
"must": [
{ "match": { "championId": 22 }}
]
}
},
"aggs": {
"items": {
"terms": {
"field": "itemId"
},
"aggs": {
"games": {
"terms": {
"field": "gameId"
},
"aggs": {
"min_buying_time": {
"min": {
"field": "timestamp"
}
}
}
},
"avg_min_time": {
"avg_bucket": {
"buckets_path": "games>min_buying_time"
}
}
}
}
}
}
If I understand your objective correctly you should be able to solve this with pipeline aggregations. More specifically to your use case, the Avg Bucket aggregation should be helpful, check out the example in the documentation, that should be very close to what you need I think.
Something like:
"avg_min_buying_time": {
"avg_bucket": {
"buckets_path": "games>min_buying_time"
}
}

Multi indices search with nested fields

I have two indices:
First, questions, have nested field answers. Second, articles do not have this field.
I try search by multi indices:
{
"index": "questions, articles",
"body":{
"query":{
"bool":{
"must":{
"nested":{
"path": "answer",
...
}
}
}
}
}
}
and get error "query_parsing_exception: [nested] failed to find nested object under path [answer]"
How I can search without errors, when one index have nested field, but another does not have?
I think you need to use the indices query and to use a different query for each index. Something like this:
GET /questions,articles/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"indices": {
"indices": [
"questions"
],
"query": {
"nested": {
"path": "answer",
"query": {
"term": {
"text": "bla"
}
}
}
}
}
},
{
"match_all": {}
}
]
}
},
{
"term": {
"some_common_field": {
"value": "whatever"
}
}
}
]
}
}
}

ElasticSearch query to search parent docs and consider that at least has one child

I have implemented parent child relation ship in elasticsearch, parent type name is participant_tests and its child type name is participant_test_question_answers, I have some search conditions for parent type as bellow:
query": {
"bool":{
"should":[
{
"range":{
"created_at":{
"gte":"2016-01-01",
"lte":"2016-05-11",
"format":"YYYY-MM-dd"
}
}
},
{
"terms":{
"created_by.id":["1000001"]
}
},
{
"multi_match":{
"query":"test human time",
"fields":[
"course_tests.course_id.course_no",
"participant_test_questions.answer_text",
"participants.first_name",
"participants.last_name",
"participants.promote_unique_user_id","result"
],
"operator":"OR"
}
}
]
}
}
Above query return result but if I want to check has_child no result returned.
I have added this lines after bool class.
"has_child": {
"type": "participant_test_question_answers",
"min_children": 1,
"query": {
"match_all": {}
}
}
Try this query:
{
"query": {
"bool": {
"should": [
{
"range": {
"created_at": {
"gte": "2016-01-01",
"lte": "2016-05-11",
"format": "YYYY-MM-dd"
}
}
},
{
"terms": {
"created_by.id": [
"1000001"
]
}
},
{
"multi_match": {
"query": "test human time",
"fields": [
"course_tests.course_id.course_no",
"participant_test_questions.answer_text",
"participants.first_name",
"participants.last_name",
"participants.promote_unique_user_id",
"result"
],
"operator": "OR"
}
}
],
"must": [
{
"has_child": {
"type": "participant_test_question_answers",
"min_children": 1,
"query": {
"match_all": {}
}
}
}
]
}
}
}

Dynamic elasticsearch queries

I've just started using elasticsearch and I'm unsure how you go about using dynamic search queries. Currently I am using something like this:
$params['body'] = '
{
"query": {
"multi_match": {
"query": "' . $terms . '",
"fields": [
"title^1",
"description"
],
"minimum_should_match": "70%"
}
},
"highlight": {
"pre_tags" : ["<b>"],
"post_tags" : ["</b>"],
"fields": {
"description": {
"fragment_size": 400
},
"title": {
"number_of_fragments": 0
}
}
}
}
}';
This works fine when $terms is just a string like ball. What I'm trying to do is be able for a user to search by string ball but maybe they want a ball from a particular location also and would have an optional location check box,if clicked a $state could be part of the query now. I looked into Bool Query
but I just wasn't sure if this was the right approach. Any guidance would be great.
Updated code
{
"query": {
"bool": {
"must": [
{
"term": {
"description": {
"value": "' . $terms .'"
}
}
},
{
"term": {
"state_id": {
"value": "' . $location . '"
}
}
}
]
}
}
}';
I'm just using a simple if(isset() in PHP to see if the terms are there and one for the location. If there is no location $_GET variable i'm just setting it as null.
The bool query is one of the best approach for querying more than one query.
curl -XPOST "http://192.168.31.16:9200/appviewx/ro/_search" -d'
{
"query": {
"bool": {
"must": [
{
"term": {
"object": {
"value": "ball"
}
}
},
{
"term": {
"location": {
"value": "state"
}
}
}
]
}
}
}'
Put these in if block
curl -XPOST. "http://192.168.31.16:9200/appviewx/ro/_search" -d'
{
"query": {
"bool": {
"must": [
{
"term": {
"object": {
"value": "ball"
}
}
}
]
}
}
}'
There are three types in bool.Must,Should,Must_not.
1)Should act as like OR condition
2)Must act as like AND condition
3)Must_not act as like NOT condition
Use filter as much as u can to increase performance. refer

Categories