Да, вам просто нужно определить атрибут CQEngine, который будет возвращать значения из вложенных объектов, которые вы хотите найти.
Например, этот атрибут будет получать названия каждого Продукта, содержащегося в Заказах, которые были размещены конкретным Пользователем.
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;
}
};
При желании вы можете добавить индекс для этого атрибута, чтобы ускорить запросы к нему.
Вот пример, который устанавливает IndexedCollection
пользователей, где у каждого пользователя есть несколько заказов, а у каждого заказа есть несколько продуктов. Продукты - это закуски, которые вы можете найти в кинотеатре. Он ищет в коллекции пользователей, заказавших «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
}
}
Кстати, я автор CQEngine, и вы можете найти полный исходный код для этого примера на сайт CQEngine. (Я только что добавил это как новый пример!)
person
npgall
schedule
11.06.2016