0

I have a Java Object, Record . It represents a single record as a result of SQL execution. Can CQEngine index collection of Record ?

My class is of the form

public class Record {
    private List<String> columnNames;
    private List<Object> values;

    ... Other getters
}

I have looked through some examples, but I have no luck there.

I want to index only specific column(s) with its name and corresponding value. Can this be achived using cqengine or is there any other alternatives to achieve the same.

Thanks.

suraj1291993
  • 474
  • 1
  • 5
  • 15
  • Why would you have separate Lists for column names and values? I'd have a Map where the key is the column name. What are you trying to accomplish? Doesn't the database index rows already? Looking at that GitHub repo, I'd wonder why you are using a SQL like abstraction. CQEngine feels like an in-memory Hibernate where you should be using domain objects. – duffymo Jul 09 '19 at 12:19
  • I could understand cqengine over simple POJOs. For my case, i have a structure like what i mentioned above. I cant use Map because, I dont want to loose position related information or use LinkedHashMap. (There are getter APIs based on columnName and position). I want to know whether fast in-memory search provided by cqengine is possible for my case. – suraj1291993 Jul 09 '19 at 12:56

1 Answers1

3

That seems to be a strange way to model data, but you can use CQEngine with that model if you wish.

(First off, CQEngine will have no use for your column names so you can remove that field.)

To do this, you will need to define a CQEngine virtual attribute for each of the indexes in your list of values.

Each attribute will need to be declared with the data type which will be stored in that column/index, and will need to be able to cast the object at that index in your list of values, to the appropriate data type (String, Double, Integer etc.).

So let's say your Record has a column called 'price', which is of type Double, and is stored at index 5 in the list of values. You could define an attribute which reads it as follows:

public static final Attribute<Record, Double> PRICE = 
    attribute("PRICE", record -> ((Double) record.values.get(5));

If this sounds complicated, it's because that way of modelling data makes things a bit complicated :) It's usually easier to work with a data model which leverages the Java type system (which your model does not). As such, you will need to keep track of the data types etc. of each field programmatically yourself.

CQEngine itself will work fine with that model though, because at the end of the day CQEngine attributes don't need to read fields, the attributes are just functions which are programmed to fetch values.

There's a bunch of stuff not covered above. For example can your values be null? (if so, you should use the nullable variety of attributes as discussed in the CQEngine docs. Or, might each of your Record objects have different sets of columns? (if so, you can create attributes on-the-fly when you encounter a new column, but you should probably cache the attributes you have created somewhere).

Hope that helps, Niall (CQEngine author)

npgall
  • 2,979
  • 1
  • 24
  • 24