google-app-enginegwtrequestfactoryobjectify

objectify query filter by list in entity contains search parameter


in an app i have an entity that contains a list of other entities (let's say an event holding a list of assigned employees)

using objectify - i need to find all the events a particular employee is assigned to.

is there a basic way to filter a query if it contains the parameter - kind of the opposite of the query in

... quick pseudocode

findAll(Employee employee) {
  ...
  return ofy.query(Event.class).filter("employees.contains", employee).list();
}

any help would be greatly appreciated


i tried just doing filter("employees", employee) after seeing this http://groups.google.com/group/objectify-appengine/browse_thread/thread/77ba676192c08e20 - but unfortunately this returns me an empty list

currently i'm doing something really inefficient - going through each event, iterating through the employees and adding them to a new list if it contains the given employee just to have something that works - i know this is not right though


let me add one thing,

the above query is not actually what it is, i was just using that because i did not think this would make a difference.

The Employee and Events are in the same entity group with Business as a parent

the actual query i am using is the following

ofy.query(Event.class).ancestor(businessKey).filter("employees", employee).list();

unfortunately this is still returning an empty list - does having the ancestor(key) in there mess up the filter?


solution, the employees field was not indexed correctly.

I added the datastore-indexes file to create a composite index, but was testing originally on a value that I added before the employees field was indexed, this was something stupid i was doing - simply having an index on the "business" field and the "employees" field fixed everything. the datastore-indexes file did not appear to be necessary, after deleting it and trying again everything worked fine.


Solution

  • Generally, you do this one of two ways:

    Put a property of Set<Key<Employee>> on the Event
    

    or

    Put a property of Set<Key<Event>> on the Employee
    

    You could also create a relationship entity, but if you're just doing filtering on values with relatively low counts, usually it's easier to just put the set property on one entity or the other.

    Then filter as you describe:

    ofy.query(Event.class).filter("employees", employee).list()
    

    or

    ofy.query(Employee.class).filter("events", event).list()
    

    The list property should hold a Keys to the target entity. If you pass in an entity to the filter() method, Objectify will understand that you want to filter by the key instead.