How to tabulate data , without doing any aggregation in Kibana? - elasticsearch

How can I tabulate data from events in kibana, without doing any aggregations?
I want to prepare a table containing 3 columns:
Hotel Name
No. of Rooms
Zipcode of Hotel
I want to extract this info from events and populate the table with above three values. How can I do this in Kibana?

You may be able to accomplish this by saving a search in the discover application and adding it to a dashboard directly (skipping the visualize step).
At the top of the "Add" panel in dashboard there is a "Searches" tab:
This tab lists all of the searches that you've saved from Discover and allows you to visualize the raw field values of documents as a table.
Hope that helps!

You can't make a table without aggregating, but (depending on your data) you may be able to get what you want by aggregating first on hotel name (Terms, Field=name, Order=Top, Size=100) then by zip code (Terms, Field=zip). The aggregation is so narrow that there is never more than one hotel in any given bucket.
Then use metric of Sum of number of rooms.
This assumes there are no two same-named hotels in the same zip code. If there are, you'll need to add a third column with some unique identifier.
I tried this using the following mapping
{"name": {"type":"string","index":"not_analyzed"},
"number-of-rooms":{"type":"integer"},
"zip": {"type":"string","index":"not_analyzed"}}
It worked fine, with the drawback that the table column header labels are "Top 100 name", "Top 100 zip" and "Sum of number-of-rooms", which isn't very user friendly.

Related

How to make Country-State-City like search in elastic Search

I want to make dependent search like when user type country and select country then on next dropdown/text search result would be from that particular Countries state, after selecting state on next text search would only based on that selected state. can anyone help to achieve this kind thing via elastic search.
i am new to elastic Search and i had basic idea of it, but didn't get idea how to do this kind of stuff where i need to search from child and feel data like map
Fist, it is important to understand how Elasticsearch store its data. You can find this kind of info here: https://www.elastic.co/guide/en/elasticsearch/reference/master/documents-indices.html
So, basically what you need is build a query with two must terms.
One for the object type (Country, State, etc).
Other for the name ("Los Angeles", "Massachussets", etc). If you want a autocomplete feature you could add a wildcard query in your list. https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
Obs: When you store your State object do not forget to store the Country name together. Since Elasticsearch is non relational you have to have Country name indexed in the State document.
Hope that it helps

Laravel elastic search display relevant data in top order

This is regarding to order the elastic search results in custom order.
I have city ids(integers) in my elastic search index, based on the user city selection the elastic search should happen.
For example:
Consider the id of Chennai is 1 & Mumbai is 2
If we have 10 records for Chennai and 20 records for Mumbai in elastic index. If the user choose Chennai, we should display the 10 records belongs to Chennai in top order and then display the remaining items.
If the user choose Mumbai, we should display the 20 records belongs to Mumbai in top order and then display the remaining items.
I am using sleimanx2/plastic laravel package for search. Appreciate if anyone help me to achieve this.
Is there any specific reason that you wish to achieve this with elastic?
The mentioned case seems to me like something i would achieve with two queries. One for the promoted, let's call them results, and one that would match everything else, except those that belong to the first query.
Then I would go ahead and display them to their respective areas or whatever.
There might be a way to merge those queries together and get your results as buckets that you can later use to create your markup accordingly, but honestly I am not sure that there is a reason to do it like this.
I hope I do not misunderstand your question,
Best Regards.

In Elasticsearch, how can I retrieve products grouped by the store that sells them?

I've got a bunch of stores, each of which sells several products, and those products have descriptions. I would like to build a search experience where the user can search for products by words in the description, and have a search result page where matching products are shown, grouped by the store that sells them. My question is:
How can I design an efficient Elasticsearch schema and query scheme that will let me query for products with the results grouped by store, with the guarantee that every store in the search results contains a complete list of items that match the query?
For instance, suppose I had the following data:
Store 1
Product 1a, description: "Peanut butter and jelly sandwich"
Product 1b, description: "Taco"
Product 1c, description: "Sandwich holder"
Store 2
Product 2a, description: "Burrito bowl"
Store 3
Product 3a, description: "Sandwich maker"
Product 3b, description: "Sandwich bread"
Product 3c, description: "Salad tongs"
In my overall application, I want a query for "sandwich" to return something like:
Store 1
product 1a
product 1c
Store 3
product 3a
product 3b
Whenever I show a store, I always want to show all hits for that store. In the domain I'm working in, there are lots of stores but each store only has a small number of products (max of around 10-20, with most stores only having 2 or 3).
I can see two ways to implement this, and both seem bad to me.
Approach #1
Index each product is a separate document. Then at query time, I could fetch every matching document and post-process them in Java to group them by store, and finally return that result. The problems I see with this approach are:
I can't use any kind of ranking, since I'm going to re-sort the results.
I also can't do any limiting; I have to fetch every single document, no matter how many there may be, since otherwise I can't guarantee that I have every product for a particular store. This will result in lots of wasted work.
Approach #2
Index each store as a separate document, with a nested field holding each product. At query time, I could retrieve stores where the product description nested field has a match on the search term. Then, once I have the stores I want to show, I'd have to run a separate query to fetch the matching products from those stores. The problems with this approach are:
I'm asking elasticsearch to do more work than necessary; internally, it had find everything I needed in the first query, but I'm asking a second query anyway
Issuing two related queries complicates the code and requires me to keep two queries in sync (e.g. I need to make sure that the documents matched in query 1 as subfields are the same documents that query 2 matches)
Can anyone more experienced with Elasticsearch than I am see a better option?
With Approach#2 I see 2 options:
Nested inner hits.
You could use top_hits with reverse_nested aggregator. You'll search for the products in query and you'll group the docs by store in the aggregator. The top_hits aggregation returns regular search hits meaning you'll get the children(products) along with the parent(store).

Elasticsearch indexed database table column structure

I have a question regarding the setup of my elasticsearch database index... I have created a table which I have rivered to index in elasticsearch. The table is built from a script that queries multiple tables to denormalize data making it easier to index by a unique id 1:1 ratio
An example of a set of fields I have is street, city, state, zip, which I can query on, but my question is , should I be keeping those fields individually indexed , or be concatenating them as one big field like address which contains all of the previous fields into one? Or be putting in the extra time to setup parent-child indexes?
The use case example is I have a customer with billing info coming from one direction, I want to query elasticsearch to see if that customer already exists, or at least return the closest result
I know this question is more conceptual than programming, I just can't find any information of best practices.
Concatenation
For the first part of your question: I wouldn't concatenate the different fields into a field containing all information. Having multiple fields gives you the advantage of calculating facets and aggregates on those fields, e.g. how many customers are from a specific city or have a specific zip. You can still use a match or multimatch query to query for information from different fields.
In addition to having the information in separate fields I would use multifields with an analyzed and not_analyzed part (fieldname.raw). This again allows for aggregates, facets and sorting.
http://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/mapping-multi-field-type.html
Think of 'New York': if you analyze it will be stored as ['New', 'York'] and you will not be able to see all People from 'New York'. What you'd see are all people from 'New' and 'York'.
_all field
There is a special _all field in elasticsearch which does the concatenation in the background. You don't have to do it yourself. It is possible to enable/disable it.
Parent Child relationship
Concerning the part whether to use nested objects or parent child relationship: I think that using a parent child relationship is more appropriate for your case. Nested objects are stored in a 'flattened' way, i.e. the information from the nested objects in arrays is stored as being part of one object. Consider the following example:
You have an order for a client:
client: 'Samuel Thomson'
orderline: 'Strong Thinkpad'
orderline: 'Light Macbook'
client: 'Jay Rizzi'
orderline: 'Strong Macbook'
Using nested objects if you search for clients who ordered 'Strong Macbook' you'd get both clients. This because 'Samuel Thomson' and his orders are stored altogether, i.e. ['Strong' 'Thinkpad' 'Light' 'Macbook'], there is no distinction between the two orderlines.
By using parent child documents, the orderlines for the same client are not mixed and preserve their identity.

different field according to categories

im trying to use elasticsearch to search through products. If product is a car for instance, it will have some field like "color", "brand", "model", "km", ...
If it is clothes, it will only have "color", "size", ...
I would like to index all this info in elastic to be able then to search cars with km between aaa km and bbb km, and / or xxxx model, same for clothes or any other products.
how can I create such field(s) in elasticsearch ? I want all products to be in same index, so user can search through all products, but also if user search a type a product, then he should be able to specify some more details according to this kind of product.
I was thinking about array field, but does that mean that all products will have all fields corresponding to all type of products even if some fields are not relevant with some products (ie clothes will have km field ??) ? Or is it possible on indexing to put just info needed corresponding to each product ?
thanks
You could use types. Create a type called car with fields color, brand, model, k etc. and then a type called cloth with fields color, size, etc.
A single index can have many types. The following two links might help you in this:
Creating indices
Creating types and mapping to the index
You could easily search across types so that you could issue a search like this to return all documents form all types within that index:
curl -XGET http://localhost:9200/_search?pretty=true -d '{"query":{"matchAll":{}}}'
Additional information - Searching across types
Having an array field is not a good idea since you would not be utilizing the ability of elasticsearch to index semi structured documents.
All the best.

Resources