appbaseio / reactivesearch

Search UI components for React and Vue
https://opensource.appbase.io/reactivesearch
Apache License 2.0
4.89k stars 470 forks source link

Display results from aggregations #237

Closed botvsbot closed 6 years ago

botvsbot commented 6 years ago

Issue Type: This is an enhancement (if not already available) Description: I am trying to write a custom query with aggregations for my list component and the results of interest are in the aggregations, rather than the query itself. If possible, I want to ignore the query results returned (ES has native support to this by specifying size: 0). Is it possible to render results returned on the aggregation buckets?

Minimal reproduction of the problem with instructions: Example query and results:

{
  "query": {
    "bool": {
      "filter": [
        { "term":  { "test": "test_name" }},
        { "term":  { "city": "san_francisco" }},
        { "range": { "validity_start": { "lte": "2018-01-29T22:30:56+0000" }}},
        { "range": { "validity_end": { "gte": "2018-01-29T22:30:56+0000" }}}
      ]
    }
  },
  "aggs": {
    "groupby": {
      "terms": {
        "field": "test_and_city"
      },
      "aggs": {
        "recent" : {
          "top_hits" : { "size": 1, "sort" : {"test_start_time":"desc"} }
        }
      }
    }
  }, "size": 0
}'

Returned result:

{
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "groupby" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "test_name_san_francisco",
          "doc_count" : 2,
          "recent" : {
            "hits" : {
              "total" : 2,
              "max_score" : null,
              "hits" : [
                {
                  "_index" : "my_index",
                  "_type" : "test",
                  "_id" : "<id>",
                  "_score" : null,
                  "_source" : {
                    "test" : "test_name",
                    "city" : "san_francisco",
                    "test_start" : "2018-01-29T22:29:59+0000",
                    "test_uuid" : "<id>",
                    "time_taken" : 9.956953141,
                    "validity_start" : "2018-01-29T22:30:09+0000",
                    "validity_end" : "2018-01-29T22:32:04+0000",
                    "status" : "0",
                    "test_and_city" : "test_name_san_francisco"
                  },
                  "sort" : [
                    1517264999000
                  ]
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Reactivesearch version: 2.1.1

Browser: Chrome

metagrover commented 6 years ago

Yes, it is possible. You can use ReactiveComponent to achieve this, where you will receive aggregations results in your component's props.

botvsbot commented 6 years ago

@metagrover Thanks for the answer. I was able to write a ReactiveComponent and able to receive aggregations. However, are these aggregations limited to usage within this particular component?

My page has 2 components:

  1. A radiobutton group (say), which queries ES and the query has an aggs parameter
  2. A ReactiveList component which displays results from the aggregations from the above query.

The issue that I am facing is that the aggregation results are now available in radiobutton component but the ReactiveList still displays query results instead of aggregation results. Is there a way to pass the aggregation results from the radiobutton component as data to the display (ReactiveList) component?

TLDR:

  1. Can I pass aggregations instead of hits as data to a display component like ReactiveList?
  2. Is it possible to extend my own react component to be a Reactive display component?
botvsbot commented 6 years ago

Also, ReactiveComponent doesn't support showFilter and URLParams properties - Any reason for this and will this be supported in future?

metagrover commented 6 years ago

It seems we have missed these props in the docs 😅 , but it supports showFilter, filterLabel and URLParams props. So it should work as expected!

botvsbot commented 6 years ago

Thanks @metagrover. Can you also answer my followup question about aggregations? Rewriting the question here: I was able to write a ReactiveComponent and able to receive aggregations. However, are these aggregations limited to usage within this particular component?

My page has 2 components:

  1. A radiobutton group (say), which queries ES and the query has an aggs parameter
  2. A ReactiveList component which displays results from the aggregations from the above query.

The issue that I am facing is that the aggregation results are now available in radiobutton component but the ReactiveList still displays query results instead of aggregation results. Is there a way to pass the aggregation results from the radiobutton component as data to the display (ReactiveList) component?

TLDR:

  1. Can I pass aggregations instead of hits as data to a display component like ReactiveList?
  2. Is it possible to extend my own react component to be a Reactive display component?
botvsbot commented 6 years ago

Can I also get all of the results for the selected filters from a Result component, instead of the single length param of onData function? I want to do some client side aggregations on the data returned by selected filters.

metagrover commented 6 years ago

Can I pass aggregations instead of hits as data to a display component like ReactiveList?

If you need to show aggregations as results in your application, you're better off putting the aggregations results that you've got in your radiobutton component in parent component's state and then using that state to render a custom results component (which doesn't need to be reactive in nature, every time state updates, it will update).

Is it possible to extend my own react component to be a Reactive display component?

Yes, you can write another ReactiveComponent and use it as Result Component, which will be reactive in nature and will be able to talk to other components without any manual logic.

Can I also get all of the results for the selected filters from a Result component, instead of the single length param of onData function? I want to do some client side aggregations on the data returned by selected filters.

Not sure if I understand this question, but we also support onAllData in Result components, check if that helps. If you're using ReactiveComponent, you've absolute control over the data, hits and aggregations, and you can create any kind of component (radiobutton or result) on your own.

Hope that helps!

metagrover commented 6 years ago

Closing this due to inactivity. Feel free to re-open if you have any more follow up questions on this!