Acen1991
Acen1991

Reputation: 11

Chaining filters with Objectify doesn't work

For some reason, I need to store my data in a Map and I don't want to declare each attribute of my objectify Entity one by one.

For instance, here is what my map would look like to:

"COMPANY_NAME" -> "something"
"TURNOVER_Min" -> 1000000 (a long value)
"CLIENT_STATUS"-> true (a boolean value)

And I would like to perform queries like that :

List<Lead> leads = ofy().load().type(Lead.class).filter("data.NET_INCOME_MIN >", 5.0).filter("data.NET_INCOME_MAX <", 100.0).list();

But I am getting no results although some data match this query...

I must tell you that it works for one filter at a tome... It also works for several filters with "=" :

Here is my entity:

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;

@Entity
public class Lead implements Serializable {

    private static final long serialVersionUID = 5920146927107230150L;

    @Id
    private String url;

    @Index
    private Date dateCreated;

    @Index
    private Map<String, Object> data = new HashMap<>();

    public Lead() {}

    public Lead(String url) {
        this.url = url;
        this.dateCreated = new Date();
    }

    public void addData(String key, Object value) {
        data.put(key, value);
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Date getDateCreated() {
        return dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }   
}

Thank you very much

Upvotes: 1

Views: 256

Answers (1)

M.Sameer
M.Sameer

Reputation: 3141

This is not your fault and not Objectify problem either.

As per the datastore documentation:

Inequality filters are limited to at most one property

To do what you want to do :

  1. Use the first filter to retrieve only the keys of the entities ( use .keys() instead of .list() ).
  2. Use the second filter to retrieve only the keys of the entities.
  3. To perform the ANDing you need to get the intersection of the two key sets retrieved above.
  4. Now as you have the keys of the entities you want and you can fetch the entities with a batch get operation.

Upvotes: 2

Related Questions