Реализация динамического поиска $ с использованием OData в ASP.netC#

Место общения программистов C#
Ответить
Anonymous
 Реализация динамического поиска $ с использованием OData в ASP.net

Сообщение Anonymous »

Я пытаюсь внедрить алгоритм поиска с помощью ODATA. В идеале я хочу взять пользовательский запрос, сравнить его с каждой строкой или GUID и дать каждой записи счет, а затем отсортировать результаты и вернуть их. (Вернут только верхние ресурсы только в случае указания Take и разрешает страсть в сочетании с Skip) < /p>
Я получил до получения оценки с использованием метода сходства, который я зарегистрировал в качестве функции DB в DBContext и и Сравнение его с порогом, но эта реализация является просто истинным/ложным фильтром для результатов, а не для динамического поиска, который я хочу.
Моя текущая реализация выглядит так (только один тип Атм, но я думаю, что я мог бы сделать его глобальным и удалить переключатель): < /p>

Код: Выделить всё

public class ExperimentalSearchBinder : QueryBinder, ISearchBinder
{
public Expression BindSearch(SearchClause searchClause, QueryBinderContext context)
{
var parameter = Expression.Parameter(context.ElementClrType, "p");

if (searchClause.Expression is not SearchTermNode node) throw new Exception("Only simple search clauses are allowed");

switch (context.ElementClrType)
{
case { } clrType when clrType == typeof(ComponentModel):
var properties = typeof(ComponentModel).GetProperties()
.Where(p => p.PropertyType == typeof(string) || p.PropertyType == typeof(Guid))
.ToList();

Expression? combinedExpression = null;

foreach (var propertyInfo in properties)
{
Expression property = Expression.Property(parameter, propertyInfo.Name);
if (propertyInfo.PropertyType == typeof(Guid))
{
property = Expression.Call(property, typeof(Guid).GetMethod("ToString", Type.EmptyTypes)!);
}
var method = typeof(DatabaseContext).GetMethod(nameof(DatabaseContext.Similarity), [typeof(string), typeof(string)]);

if (method is null)
{
throw new MissingMethodException($"Method not found: {nameof(DatabaseContext.Similarity)}");
}

var searchTerm = Expression.Constant(node.Text);
var similarityCall = Expression.Call(method, property, searchTerm);
var comparison = Expression.GreaterThanOrEqual(similarityCall, Expression.Constant(0.1));

combinedExpression = combinedExpression == null ? comparison : Expression.OrElse(combinedExpression, comparison);
}

if (combinedExpression is null)
{
throw new Exception("Failed to build combinedExpression");
}

return Expression.Lambda(combinedExpression, parameter);

default:
//Default simply tries to match ID
//TODO: Make a better default implementation
var defaultProperty = Expression.Property(parameter, "Id");
var defaultSearchTerm = Expression.Constant(node.Text);
var defaultComparison = Expression.Equal(defaultProperty, defaultSearchTerm);

return Expression.Lambda(defaultComparison, parameter);
}
}
}
< /code>
Для реализации сортировки я бы в идеале хотел бы, чтобы SQL выглядел примерно так: < /p>
SELECT *
FROM (
SELECT *, SIMILARITY(name, '801') + similarity(description, '801') as Score
FROM component
) subquery
WHERE Score > 0.3 order by Score desc;
Я следил за этим сообщением в качестве примера: https://devblogs.microsoft.com/odata/co ... ore-odata- 8/#Register- $ Search-Binder


Подробнее здесь: https://stackoverflow.com/questions/793 ... in-asp-net
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»