Elasticsearch Paginate Aggregation - php

Is there a way in elasticsearch to paginate aggregation results?
I tried 'partition' and 'num_partitions' without success.
'session': {
'terms': {
'field': 'data.session.keyword',
'size': 100,
'include': {'partition':1, "num_partitions":10},
'order': sortQuery
}
}

Related

Convert Mysql Query into Elastic search query

i'm working on elastic search but not expert in making elastic search queries. find my query bellow and if possible to convert into elasticsearch query then take thanks in advance
SELECT
`currency`.`id` AS `cur_id`,
`currency`.`currency_name` AS `cur_name`,
`currency`.`currency_code` AS `cur_code`,
`currency`.`currency_slug` AS `cur_slug`,
`currency`.`logo` AS `cur_logo`,
`currency`.`added_date` AS `cur_added_date`,
`currency`.`mineable_or_not` AS `mineable_or_not`,
`currency`.`market_cap` AS `cur_market_cap`,
`currency`.`circulating_supply` AS `cur_circulating_supply`,
`currency`.`max_supply` AS `cur_max_supply`,
`currency`.`total_supply` AS `cur_total_supply`,
`currency`.`market_cap` AS `ng_cur_market_cap`,
`currency`.`added_date` AS `ng_cur_added_date`,
`currency`.`circulating_supply` AS `ng_cur_circulating_supply`,
`calculations`.`volume_1hour` AS `cal_volume_1hour`,
`calculations`.`volume_24hour` AS `cal_volume_24hour`,
`calculations`.`volume_168hour` AS `cal_volume_168hour`,
`calculations`.`volume_720hour` AS `cal_volume_720hour`,
`calculations`.`volume_24hour_btc` AS `cal_volume_24hour_btc`,
`calculations`.`current_price` AS `cal_current_price`,
`calculations`.`percentage_change` AS `cal_percentage_change_24h`,
`calculations`.`percentage_change_1h` AS `cal_percentage_change_1h`,
`calculations`.`percentage_change_168h` AS `cal_percentage_change_168h`,
`calculations`.`volume_24hour` AS `ng_cal_volume_24hour`,
`calculations`.`current_price` AS `ng_cal_current_price`
FROM `currency`
JOIN `calculations` ON `calculations`.`currency_id` = `currency`.`id`
WHERE `calculations`.`update_status` = 1 AND `currency`.`currency_type` != 3 AND `calculations`.`update_status` = 1 AND `currency`.`status` = 1
ORDER BY `market_cap` DESC
LIMIT 100
As eliasah commented, there is no join operation in elastic search.
Joining queries
In general you can't really perform joining queries in ES. You can have a parent/child relationship on documents that are under the same index, but that is something I would not opt into. My best advice is to denormalize your data and have each document as 'self-contained' as possible. In this specific example, one possible solution is to store the calculations inside the currency, you would end up with a query like:
{
"_source": ["id", "logo", ..., "calculations.volume_1h","calculations.volume_24h",...],
"query": {
"bool": {
"must":[
{
"match":{
"calculations.update_status":1
}
},
{
"match":{
"currency_type":3
}
},
{
"match":{
"status":1
}
}
]
},
"sort" : [
{
"market_cap": {
"order": "desc"
}
}
]
"size":100
}

elasticsearch aggregations on substring

I have a field indexed as String in elasticsearch 5
For example 20090219 , 20100416 etc
I can make a aggregation this data, But I want to aggregate on substring.
that is on
2009,2010
I don't want to convert to date. I want to get first 4 characters and get the count.
This is my current code.Very new to Elasticsearch
$params['body']["aggs"]["Year"]["terms"]["field"] = "PublicationDate.keyword";
$params['body']["aggs"]["Year"]["terms"]["size"] = 10;
$params['body']["aggs"]["Year"]["terms"]["order"]["_count"] = "desc";
You can use elasticsearch script feature to achieve this.
GET my-index/_search
{
"aggs" : {
"my-agg" : {
"terms" : {
"script": {
"inline": "doc['PublicationDate.keyword'].getValue().substring(0,4)"
},
"size": 10,
"order" : { "_count" : "desc" }
}
}
}
}
I don't know equivalent php script for above command, but believe you will able to make it work in php.
this did the task
$params['body']["aggs"]["PublicationYear"]["terms"]["script"] = "_value.substring(0,4)";

Elasticsearch "Join" tables

I need to do "Join" between 2 indexes (tables) and preform a check on specific field on documents that exists in both indexes.
I want to add condition like "dateExpiry" below, but I get an error. Is it possible to join 2 or more indexes?
GET cache-*/_search
{
"query": {
"bool": {
"must_not": [
{
"query": {
"terms": {
"TagId": {
"index": "domain_block-2016.06",
"type": "cBlock",
"id": "57692ef6ae8c50f67e8b45",
"path": "TagId",
"range" : {
"dateExpiry" : {
"gte" : "20160705T12:00:00"
}
}
}
}
}
]
}
}
}
Filters within a Terms Query Lookup are currently not supported. However, Elasticsearch has some great documentation on joins / relationships here.
Your best bet may be to run two queries against Elasticsearch - one to fetch the list of TagIds, then another that includes the list as an exclusion clause.

Elasticsearch either or match query

I am trying to write a query to search for a products on two columns called category1 and category2. I am working using elastic search php client and tried with match should query but this giving me wrong results because of match of substring.
But i am looking for exact match with OR operation on two columns. I am new to this please guide me.
$params['index'] = 'furnit';
$params['type'] = 'products';
$params['body']['query']['bool']['should'] = array(
array('match' => array('category1' => $category->name)),
array('match' => array('category2' => $category->name)),
);
$results = $this->elasticsearch->search($params);
If you are not searching then using a bool query in this scenario is not the right way to do it in elasticsearch. Queries are used when you are searching something and relevancy of your search keyword and score of matching documents matters.
Here you can apply a bool filter of elasticsearch to filter out the desired results. Using filters with queries (filtered query) is right way to do it as it excludes all non-matching documents and then you can search for desired documents by using match queries.
here's an example of a bool filter
{
"from": 0,
"size": 50,
"sort": [
{
"name" : {
"order": "asc"
}
}
],
"query": {
"filtered": {
"query": {
"match_all" : {}
},
"filter": {
"bool": {
"should": [
{
"term": {
"category1" : "category1"
}
},
{
"term": {
"category2" : "category2"
}
}
]
}
}
}
}
}
you can refer to docs as well (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html)
Maybe your problem is you have used default analyzer (which is standard analyzer).
could you give me your mapping ?
I suggest you to change to use not_analyzer when indexing and use term filter/query.
You could use put mapping here to setting for your analyzer: Put Mapping
Edit: I have created a gist for you, check it here:
Mappings & Terms Filter

elastica with terms and facets

I am faily new to elasticsearch and try to get along with elastica. I try to find out what Items are often togehter in a set of items when one of them is 2 and/or 7. So the index contains a lot of nested sets of items. The mutual items will be extracted with facets. But I don't seem to get the following query converted to elastica:
curl -X POST "http://localhost:9200/ratings/rating/_search?pretty=true" -d '
{
"query": {
"terms": {
"bookid": [2, 7],
"minimum_match" : 1
}
},
"size": 0,
"facets": {
"bookid": {
"terms": {
"field": "bookid"
}
}
}
}'
I was trying this:
// Load index
$index = $client->getIndex('ratings');
$type = $index->getType('rating');
// We want a Terms query.
$query = new Elastica_Query_Terms();
// Setting Terms
$query->setTerms('bookid', $bookids);
// Facets
$facet = new Elastica_Facet_Query('matches');
$facet->setField( 'bookid' )
->setSize(100);
$facet->setQuery($query);
$resultSet = $type->search($query);
return $resultSet;
but no luck so far. How do I add the facet properties?
Elastica query classes have an addFacet method, so rather than set the query on the facet, it makes more sense to add the facet to the query.
$facet = new Elastica_Facet_Query('matches');
$facet->setField('bookid')
->setSize(100);
$query = new Elastica_Query_Terms();
$query->setTerms('bookid', $bookids);
$query->addFacet($facet);

Categories