Distinguish tags from fields in InfluxDB "SELECT *" results - influxql

Assume you're given an InfluxDB measurement you haven't seen before and you run,
SELECT * FROM measurement
How can you tell which of the keys returned are tags, and which are fields? The InfluxDB shell sorts the keys alphabetically, so unlike the Line Protocol, fields don't come before tags.

You can see which is which with
show field keys from <measurement>; show tag keys from <measurement>

There seems to be no indication of which SELECT result columns are fields and which are tags, but you can select all fields separately from tags with
SELECT *::field FROM <measurement>

Related

How to define a tags / value query in Grafana 7.4?

I am having some trouble understanding the concept of Value groups/tags in Grafana 7.4.x with MySQL as a data source.
My main query gets the Countries
SELECT
NAME as __text,
id AS __value
from
countries
The tags query gets the Continents
SELECT
NAME as __text,
id AS __value
from
continents
That works so far, tags are shown in the list, but nothing happens once I click on them.
My tags query:
continents.$tag.*
The tags query seems to be the problem. Any help is greatly appreciated.
3 queries are involved:
The first one is under "Query Options" -> "Query": This one should list all the values (all the countries in your case).
The second query is the "Tags query" under "Value groups/tags": This query should list all the Tags you want (continents).
The third query is "Tag values query": This is where the magic happens, this query should return all the different values matching the selected tags, so, you must add a WHERE clause somewhere that Grafana will use to create a query to get the correct values, ...WHERE continent = '$tag'. <- $tag will automatically be replaced by a list of tags the user has chosen.
Be aware that the official documentation provides examples for InfluxDB datasource, since you are using MySQL, you must use SQL queries everywhere, so continents.$tag.* is invalid.

Using MYSQLI to select rows in which part of a column matches part of an input

I have a database in which one of the columns contains a series of information 'tags' about the row that are stored as a comma-separated list (a string) of dynamic length. I am using mysqli within PHP, and I want to select rows in which any of these items match any of the items in an input string.
For example, there could be a row describing an apple, containing the tags: "tasty, red, fruit, sour, sweet, green." I want this to show up as a result in a query like: "SELECT * FROM table WHERE info tags IN ('blue', 'red', 'yellow')", because it has at least one item ("red") overlapping. Kind of like "array_intersect" in PHP.
I think I could use IN if each row had only one tag, and I could use LIKE if I used only one input tag, but both are of dynamic length. I know I can loop over all the input tags, but I was hoping to put this in a single query. Is that possible? If not, can I use a different structure to store the tags in the database to make this possible (something other than a comma separated string)?
I think the best would be to create tags table (id + label) then separate "table_tags" table which holds table_id and tag_id.
that means using JOINS to get the final result.
another (but lazy) solution would be to prefix and suffix tags with commas so the full column contains something like:
,tasty,red,fruit,sour,sweet,green,
and you can do a LIKE search without being worried about overlapping words (i.e red vs bored) and still get a proper match by using LIKE '%,WORD,%'

Postgres/full text search showing a preview of part of a document

I'm using postgres 9.3 with full text search and I'm running a query like
select * from jobs where fts ## plainto_tsquery('pg_catalog.english','search term');
I'm getting the proper results, however, I'd like to be able to get a portion of the search results that match the terms searched. The FTS column is just a to_tsvector() of the description column. What I'd like to do is show a short excerpt of the description, with the terms highlighted. Any ideas on how I'd achieve this?
This is what the ts_headline() function is intended for.
It is designed to deliver you excerpts or highlights of the "original" text you have normalized. The most basic usage would be this:
SELECT ts_headline(description, keywords) as result
FROM jobs, plainto_tsquery('pg_catalog.english','search term') as keywords
WHERE fts ## keywords;
Note that "description" in this query is my guess to the name of your column that holds the original text and "fts" is the guess for the column that contains the normalized text.
This query will return a result set containing an excerpt of your orignal text with the matching tokens highlighted through HTML <b> tags.
There is a comma separated string of optional values you can pass into this function to alter its behavior. You could, for example, alter the surrounding tags you will get back by setting the StartSel and EndSel values:
SELECT ts_headline(description, keywords, 'StartSel=<em>,StopSel=</em>') as result
FROM jobs, plainto_tsquery('pg_catalog.english','search term') as keywords
WHERE fts ## keywords;
Now the <b> tags will become <em> tags. Actually, they do not have to be HTML tags, you can pass in (almost) any string.
Another popular value to set is the amount of excerpts you wish to see by setting the MaxFragments values to control the maximum amount of possible excerpts to return in combination with the MaxWords and MinWords values to set how much text should surround each excerpt.
SELECT ts_headline(description, keywords, 'MaxFragments=4,MaxWords=5,MinWords=2') as result
FROM jobs, plainto_tsquery('pg_catalog.english','search term') as keywords
WHERE fts ## keywords;
The above query will now show a maximum of four possible excerpts and have a word boundary set between two and five words.
If you wish to simply show the whole document with the results highlighted, you could use the HighlightAll value, which overrides all fragment values set:
SELECT ts_headline(description, keywords, 'HighlightAll=true') as result
FROM jobs, plainto_tsquery('pg_catalog.english','search term') as keywords
WHERE fts ## keywords;
Note: beware of using ts_headline() for it is a possible bottleneck in performance. For each record you wish to highlight, the database has to go and fetch the whole text, parse it and insert the desired start and end elements.
Please use the function with great care and only set it loose on a small portion (top five or top ten records) of your complete result set.

Sphinx Filtering based on categories using OR

I have the following text fields I search with Sphinx: Title, Description, keywords.
However, sometimes things are narrowed down using categories. We have 3 category fields: CatID1, CatID2 and CatID3.
So, for example, I need to see if the word "Kittens" is in the Title, Description, or Keywords, but I also want to filter so that only items that have the categories (Animals - ID Number 8) or (Pets - ID Number 9) or (Felines - Category ID Number 10) in either of those CatID fields.
To clarify, only show items that have a 8,9 or 10 in CatID1, 2 or 3.
Any ideas on how I would accomplish this using sphinx filtering or searching the CatID1 fields as keywords?
Note: I am able to filter and it works great only using one category, i.e:
if(!empty($cat_str)) {
$cl->SetFilter( 'catid1', array( $cat_str ));
}
Thanks!
Craig
SetFilter takes an array. In your example you are putting $cat_str into an array. A array of one item.
So you just needs to build array with all the ids.
$cl->SetFilter( 'catid', array( $cat1, $cat2, $cat3 ));
But thats not very flexible. So you probably build the array dynamically, rather than hard-coded like that. But thats upto your application how to build the array.
But also storing the ids, in three sperate attributes, makes it hard to search. Notice in the above example, just noticed a attribute called catid. This would be a single multi-value attribute, that contains the ids from all three cat fields. That way its easy to search for ids in ANY of the columns at once.
http://sphinxsearch.com/docs/current.html#mva
if using a sql source, could do with something like
sql_query = SELECT id, title ... , CONCAT_WS(',', CatID1, CatID2 and CatID3) as catid FROM ...
sql_attr_multi = uint catid from field;

Combining all text fields into a single searchable field?

One would normally have this query in their sphinx.conf file :
sql_query = SELECT id,text_field1,text_field2,text_field3 FROM table_name
Would there be much difference if I combine all fields into one searchable text field like so?
sql_query = SELECT id, CONCAT(text_field1,text_field2,text_field3) as searchable_text FROM table_name
What benefits does one have over the other?
Thanks!
I think either way is generally fine... however, Sphinx has the ability to focus queries at certain fields (see the extended query syntax examples). If you merge all the columns into one field, you'll lose that ability.
You'll also lose the ability to weight certain fields higher than others.
CONCAT(text_field1,text_field2,text_field3) is wrong
use CONCAT(text_field1,' ',text_field2,' ',text_field3)
but it's better to let index separate fields
search returns same result but you can select one of list if needed
'#text_field2 foo'