objectify query filter by list in entity contains search parameter
Asked Answered
S

2

7

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.

Systematize answered 26/3, 2012 at 6:11 Comment(0)
K
4

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.

Kingly answered 26/3, 2012 at 16:28 Comment(7)
this is actually exactly what i'm doing but for some reason i can't get it to work. 2 things - instead of a Set, i'm using a List<Key<Employee>> - would that make any difference? Also, they are in an entity group with a Business as a parent - so the query is actually ofy.query(Event.class).ancestor(businessKey).filter("employees", employee).list() - but this is returning an empty list - I didn't think having the query with an ancestor key in there would mess anything upSystematize
Neither the List nor the ancestor should make a difference - although the ancestor() + filter() will probably require a compound index. Have you @Indexed the employees property? That will be necessary, even with the compound index.Kingly
@vandus Since sean christie doesn't seem to answer, did you manage to make this work? I couldn't.Coincidental
Nope, I gave it up in the end and never worked with it again. Sorry :/Principle
If you have saved an entity with an indexed list property, you can filter on that value. It works. Maybe you added @Index and didn't resave the entity?Kingly
Unfortunately I did resave the entity after having added the @Index annotation. When I try to filter on a List<String> list, providing a String myString, the query ofy().load().type(X.class).filter('list =', myString) will always return an empty Collection.Coincidental
I can't tell what you're doing wrong, but it does work. This test passes: github.com/objectify/objectify/blob/master/src/test/java/com/…Kingly
S
1

Example : /***************************************************/

@Entity

@Cache

public class News {

@Id Long id;
String news ;
@Index List<Long> friend_list = new ArrayList<Long>();

// My friends who can see my news , exemele : friend_list.add(id_f1); friend_list.add(id_f2); friend_list.add(id_f3);

//To make an operation on "friend_list", it is obligatory to index it

}

/*************************************************/

public News(Long id_f){

    List<Long> friend_id = new ArrayList<Long>();
    friend_id.add(id_f);

Query<Nesw> query = ofy().load().type(News.class).filter("friend_list in",friend_id).limit(limit); 

//To filter a list, just after the name of the field you want to filter, add "IN".

//here ==> .filter("friend_list in",friend_id);

// if friend_list contains "id_friend" ==> the query return value

    .........

}

Solita answered 21/7, 2017 at 16:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.