influxdb-cxx icon indicating copy to clipboard operation
influxdb-cxx copied to clipboard

getTags vs. getFields

Open lvn2007 opened this issue 1 year ago • 6 comments

Not sure if I understand it correctly but it seems that the getTags call is returning Field instead of tags. This was validated using Influx CLI client:

CMD:

SHOW FIELD KEYS ON BENCH_DB

CMD Returns:

> SHOW FIELD KEYS ON BENCH_DB
name: BENCH_DB
fieldKey fieldType
-------- ---------
col0     string
col1     string
col10    string
col11    string
col12    string
col13    string
col14    string
col15    string
col16    string
col17    string
col18    string
col19    string
col2     string
col20    string
col21    string
col22    string
col23    string
col24    string
col25    string
col26    string
col27    string
col28    string
col29    string
col3     string
col30    string
col31    string
col4     string
col5     string
col6     string
col7     string
col8     string
col9     string
>

getTags: When calling getTags, it's returning fields shown in CMD. However, calling getFields, it's not returning anything.

std::vector<influxdb::Point> unaryQueryRep = influxClient->query("SELECT * FROM BENCH_DB WHERE time = 946684800ms");

for (auto j: unaryQueryRep) {
    std::cout << j.getTags() << "\n";
}

lvn2007 avatar Aug 19 '24 22:08 lvn2007

Please add versions of the library and influxdb version used.

Is there a minimal example to reproduce the issue?

The related test case might be a good starting point, but does not show the problem.

offa avatar Aug 20 '24 16:08 offa

I'm using InfluxDB v1.6.7~rc0 and influxcxx v0.7.1 After some debugging, it seems that for addField(key, value), if I have value as string, inserted data will become Tag instead of Field. However, if I remove "asdf" in makeSinglePoint function, values exist in .getFields() call.

Please see the below for the example that reproduce the said issue.

#include <InfluxDBFactory.h>
#include <iostream>
#include <chrono>
#include <string>
#include <vector>

influxdb::Point makeSinglePoint() {
    influxdb::Point toReturn{"BENCH_DB"};

    std::chrono::time_point<std::chrono::system_clock> timestamp(std::chrono::milliseconds(946684800));
    toReturn.setTimestamp(timestamp);

    for (int i = 1; i < 32; i++) {
        toReturn.addField("col" + std::to_string(i - 1), "asdf" + std::to_string(i));
    }
    return toReturn;
}

int main(int argc, char const *argv[])
{
    // Init InfluxDB instances
    auto db = influxdb::InfluxDBFactory::Get("http://192.168.1.155:8086?db=BENCH_DB");

    // Create DB
    db->createDatabaseIfNotExists();

    // Make single Point
    influxdb::Point currPoint = makeSinglePoint();

    // Insert
    db->write(std::move(currPoint));

    // Query
    std::vector<influxdb::Point> unaryQueryRep = db->query("SELECT * FROM BENCH_DB WHERE time = 946684800ms");

    std::cout << unaryQueryRep.at(0).getFields() << "\n";
}

lvn2007 avatar Aug 22 '24 22:08 lvn2007

Thanks, I'm able to reproduce the issue with your example.

offa avatar Aug 25 '24 15:08 offa

The original implementation uses the type to determine field (everything except string) or tag (string).

The response JSON doesn't provide any information to separate field and tag strings, but only columns and values.

offa avatar Sep 01 '24 15:09 offa

the func in BoostSupport.cxx std::vector<Point> queryImpl(Transport* transport, const std::string& query)

// cast all values to double, if strings add to tags
try
{
    point.addField(column, boost::lexical_cast<double>(value));
}
catch (...)
{
    point.addTag(column, value);
}

make the string type field return as tag when query

ly496752519 avatar Mar 18 '25 04:03 ly496752519

You mean to add it as field rather than tag?

offa avatar Mar 27 '25 14:03 offa