RavenDb дублирует поиск предикатов граненого поиска - PullRequest
2 голосов
/ 29 октября 2011

Учитывая, что у меня есть следующий класс

class Car { 
    public string Id;
    public string Make;
    public string Model;
    public double Price;
    public IEnumerable<string> Locations;
}

мои требования состоят в том, чтобы получить набор результатов для пользователя и отобразить некоторые грани поверх него для критериев, которые отражены в следующем утверждении ниже.

session.Query<Car>()
    .Where(c => c.Make == "Mazda")
    .Where(c => c.Price < 3000)
    .Where(c => c.Locations.Any(l => l.In("VIC", "NSW")))
.ToList();

Учитывая, что приведенный выше оператор извлекает набор результатов, в идеале, без изменения способа построения моего предиката, если я хочу получить фасеты, которые я бы сделал

session.Query<Car, Car_Facets>()
    .Where(c => c.Make == "Mazda")
    .Where(c => c.Price < 3000)
    .Where(c => c.Locations.Any(l => l.In("VIC", "NSW")))
.ToFacets("facets/CarFacets");

где я не изменяю фактический предикат, а только изменяю, к какому индексу идти, и расширению ToFacets.

и мой индекс будет выглядеть так

public class Car_Facets : AbstractIndexCreationTask<Car> {  
    public Car_Facets() {
        Map = cars => from car in cars 
                              select new { car.Make, car.Model, car.Price, car.Locations};
    }
}   

это не будет работать. мои грани возвращаются пустыми. Чтобы получить фасеты для данного требования запроса, мой запрос необходимо изменить, чтобы он выглядел как

session.Query<Car, Car_Facets>().AsProjection<CarOnLocation>
   .Where(c => c.Make == "Mazda")
   .Where(c => c.Price < 3000)
   .Where(c => c.Location.In("VIC", "NSW"))
.ToFacets("facets/CarFacets");

где свойство местоположения было выровнено. соответствующий индекс

public class Car_Facets : AbstractIndexCreationTask<Car> {  
    public Car_Facets() {
        Map = cars => from car in cars 
                      from location in car.Locations
                      select new {car.Make, car.Model, car.Price, Location = location};
    }
}

фон : для простоты я указал предикаты как, где предложения в моих вышеупомянутых операторах запроса. В моем коде приложения каждый предикат индивидуально определен в классах спецификаций. Используя ioc, я получаю все спецификации, удовлетворяющие заданному интерфейсу, а затем строю выражение из всех спецификаций и, наконец, применяю предикат из выражения к вышеуказанному запросу. Это дает мне композиционную модель, в которой, если у нас есть требования, для которых необходимо добавить новый предикат, можно создать новый класс спецификации, и он будет выбран ioc и применен без каких-либо изменений к любым другим классам

проблема но я больше не могу этого делать, как я проиллюстрировал выше в коде, где мой предикат изменяется при запросе к вложенным коллекциям при получении фасетов. Следовательно, я должен определить эти предикаты дважды или записать их в двух местах: одно для запроса набора результатов, а другое для запроса фасета. Если требования изменятся, мне нужно будет обновить запросы в двух местах.

вопрос Есть ли способ обойти это так, чтобы я мог повторно использовать одни и те же предикаты для извлечения как результирующих наборов, так и аспектов, когда используется вложенный критерий сбора?

Было бы здорово, если бы при одних и тех же требованиях мне не приходилось писать запросы двумя разными способами: один для получения результатов и один для получения фасетов.

...