Yes, you just need to define a CQEngine attribute which will return the values from the nested objects you want to search.
For example, this attribute will retrieve the names of each Product, which is contained in the Orders, which were placed by a particular User.
static final Attribute<User, String> PRODUCT_NAMES_ORDERED = new MultiValueAttribute<User, String>() {
public Iterable<String> getValues(User user, QueryOptions queryOptions) {
return user.orders.stream()
.map(order -> order.products).flatMap(Collection::stream)
.map(product -> product.name)::iterator;
}
};
You could optionally add an index on this attribute, to accelerate queries on it.
Here's an example which sets up an IndexedCollection
of Users, where each user has a number of Orders, and each order has a number of Products. The products are snacks you might find at a cinema. It searches the collection for users who ordered a "Snickers Bar".
package com.googlecode.cqengine.examples.nestedobjects;
import com.googlecode.cqengine.*;
import com.googlecode.cqengine.attribute.*;
import com.googlecode.cqengine.query.option.QueryOptions;
import java.util.*;
import static com.googlecode.cqengine.query.QueryFactory.*;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
public class NestedObjectsExample {
public static void main(String[] args) {
Order order1 = new Order(asList(new Product("Diet Coke"), new Product("Snickers Bar")));
Order order2 = new Order(singletonList(new Product("Sprite")));
User user1 = new User(1, asList(order1, order2));
Order order3 = new Order(asList(new Product("Sprite"), new Product("Popcorn")));
User user2 = new User(2, singletonList(order3));
Order order4 = new Order(singletonList(new Product("Snickers Bar")));
User user3 = new User(3, singletonList(order4));
IndexedCollection<User> users = new ConcurrentIndexedCollection<>();
users.addAll(asList(user1, user2, user3));
users.retrieve(equal(PRODUCT_NAMES_ORDERED, "Snickers Bar")).forEach(user -> System.out.println(user.userId));
// ...prints 1, 3
}
}
BTW I'm the author of CQEngine, and you can find the complete source for this example on the CQEngine site. (I have just added this as a new example!)