2013-02-21 2 views
1

В моем проекте я пытаюсь реализовать Граничный поиск с использованием Linq. Я не хочу использовать Solr, Lucene и т.д ...Граничный поиск в linq

Мой DB:

продукты

+----+------+ 
| id | name | 
+----+------+ 
| 1 | prod1| 
+----+------+ 
| 2 | prod2| 
+----+------+ 

значений атрибутов

+----+--------+---------+ 
| id | name | alias | 
+----+--------+---------+ 
| 1 | Weight | weight | 
+----+--------+---------+ 
| 2 | Height | height | 
+----+--------+---------+ 

+----+---------------+---------+---------+ 
| id | attribute_id | value | alias | 
+----+---------------+---------+---------+ 
| 1 |  1  | 10 g | 10m | 
+----+---------------+---------+---------+ 
| 2 |  1  | 20 g | 20m | 
+----+---------------+---------+---------+ 
| 3 |  2  | 10 m | 10m | 
+----+---------------+---------+---------+ 
| 4 |  2  | 20 m | 20m | 
+----+---------------+---------+---------+ 

products_values ​​

+---------------+---------+ 
| product_id | value_id| 
+---------------+---------+ 
|  1  | 1  | 
+---------------+---------+ 
|  1  | 2  | 
+---------------+---------+ 
|  1  | 3  | 
+---------------+---------+ 
|  2  | 1  | 
+---------------+---------+ 

Запрос для выбора, например, : site.com/filter/weight=10g_20g;height=10h/

ПОКО модель для фильтра:

public class Filter 
{ 
public string Attribute { get; set; } 
public IEnumerable<Value> Values{ get; set; } 
} 

Эта модель использует для пользовательской модели связывания.

Но теперь, заполнив модель фильтра, я не знаю, как реализовать выбор продуктов и выбирать «активные» значения в фильтре (с включенными функциями подсчета). Таблица заполнения фильтров и продуктов должна быть разделена? Или, может быть, в одном действии? Я рад видеть пошаговое руководство по реализации фасетного поиска с использованием Linq.

ответ

0

Реляционная база данных и LINQ - это плохие начала для поиска грани, но я разделяю вашу мечту ... То, что я вижу выше, не кажется мне грандиозным в техническом смысле, поскольку вы можете динамически наращивать отношения OR, чтобы результаты из таблицы продуктов, используя PredicateBuilder. Если я понимаю, что вам нужен запрос, который проверяет связку отношений OR для каждого псевдонима в сочетании с отношением OR для каждого значения. Любой продукт, который соответствует псевдониму и любому из значений, является совпадением. Если псевдоним не совпадает, вы не беспокоитесь о значениях. После того, как вы создали базовый запрос, вы делаете группу, чтобы удалить дубликаты.

Ниже приведен пример итерации списка значений и построения и набора запросов отношений. В вашем случае вы будете строить OR отношений между псевдонимами. В этом случае мои queryBuilders содержат набор значений для соответствия, я передаю текущий Queryable, потому что вам нужно связать эти утверждения вместе.

public static IQueryable<MeetingPayment> GetViewSpecificQuery(IQueryable<MeetingPayment> query, IInvoiceViewDetail viewToUse, IEnumerable<IInvoiceViewQueryBuilder> queryBuilders) 
     { 
      Expression<Func<MeetingPayment, bool>> predicate = PredicateBuilder.True<MeetingPayment>(); 

      foreach (IInvoiceViewQueryBuilder builder in queryBuilders) 
      { 
       Expression<Func<MeetingPayment, bool>> predicateItem = builder.GetQuery(predicate, viewToUse); 

       if (predicateItem != null) 
       { 
        predicate = predicate.And(predicateItem.Expand()).Expand(); 
       } 
      } 

      return query.Where(predicate.Expand()); 
     } 

Это индивидуальный фильтр, где соотношение OR создается между коллекцией значений, как вы делаете с 10g и 20g.

public Expression<Func<MeetingPayment, bool>> GetQuery(Expression<Func<MeetingPayment, bool>> query, IInvoiceViewDetail viewToUse) 
      { 
        var ids = viewToUse.InvoiceStatuses.Select(x => x.Id).ToList(); 

        if (!ids.Any()) return null; 

        var predicate = PredicateBuilder.False<MeetingPayment>(); 

        foreach (var id in ids) 
        { 
         int? closure = id; 
         predicate = predicate.Or(x => x.InvoiceStatus == (InvoiceStatusEnum) closure); 
        } 

        return predicate; 
      } 

Удачи.

Смежные вопросы