我已经用C#创建了一个.net MVC应用程序,该应用程序列出了组织,当前在数据库(SQLServer)中有6000条记录。组织表中的字段为:
当前搜索是使用linq完成的,例如:
iList<Organisation> orglist = myOrgs.Where(x => x.Title.Contains('abc') ||
x.ContactPerson.Contains('abc') ||
x.Details.Contains('abc') ||
x.Keywords.Contains('abc'))
.OrderBy(x => x.Title).ToList();
然后按标题对结果进行排序。哪个不合适。
如果有人搜索“酒精支持”,我希望以上结果在列表顶部。
我希望对以下结果进行排名:
正在寻找实现此目标的最佳方法的建议,或者是否有人知道已经有这样做的算法/库?
**更新** 我现在正在寻找一个更简单的解决方案,请参见以下链接:
答案 0 :(得分:0)
需求的
对于每种要求,我们将进行SQL调用
每个SQl调用我们将仅返回行ID的
然后我们按顺序将ID分组
我们将进行最终的SQL调用
在这里我们将使用EF
db.Orgs.Where(w => w.Title.Contains(search_query))
.Select(s => s.Id).ToList();
这种对linq2Sql的使用包含将转换为sql WHERE IN
在这里我们将使用普通sql 位置 + 喜欢 + AND
Select Id From Orgs where
Title LIKE '%' + @param0 +'%'
and Title LIKE '%' + @param1 +'%'
在这里我们将使用普通sql 位置 + 或 + 并且
Select Id From Orgs
where Title LIKE '%' + @param0 +'%'
or Title LIKE '%' + @param1 +'%'
在这里我们将使用普通sql 位置 + 或 + 并且
Select Id From Orgs
Where Keywords LIKE '%' + @param0 +'%'
or Keywords LIKE '%' + @param1 +'%'
在这里我们将使用EF
db.Orgs
.Where(w => w.Content.Contains(search_query)).
Select(s => s.Id).ToList();
这种对linq2Sql的使用包含将转换为sql WHERE IN
我们将根据订单检索对ID进行排序
var ids = new Dictionary<int, int>();
foreach (var id in Ids1)
{
int val;
if (!ids.TryGetValue(id, out val))
{
ids.Add(id, ids.Count());
}
};
.
.
ids.OrderByDescending(o => o.Value)
.Select(s => s.Key) .ToArray();
在这里我们将使用普通sql 订购依据 + 随后的情况
Select * from Orgs
where Id in ( 2 , 1 )
ORDER BY CASE id
WHEN 2 THEN 0
WHEN 1 THEN 1
ELSE 2 END
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp9
{
class Program
{
static void search(string search_query)
{
//////////////////////////////////////////////////
var terms = search_query.Split(' ');
//////////////////////////////////////////////////
var Ids1 = db.Orgs.
Where(w => w.Title.Contains(search_query))
.Select(s => s.Id).ToList();
var Ids2 = db.Database
.SqlQuery<int>(getWhere("Title", "AND"), terms)
.ToList();
var Ids3 = db.Database
.SqlQuery<int>(getWhere("Title", "OR"), terms)
.ToList();
var Ids4 = db.Database
.SqlQuery<int>(getWhere("Keywords", "OR"), terms)
.ToList();
var Ids5 = db.Orgs
.Where(w => w.Content.Contains(search_query))
.Select(s => s.Id).ToList();
var ordered_ids = reorderList(Ids1, Ids2, Ids3, Ids4, Ids5);
var OrderedData = db.Database.SqlQuery<Org>(getOrdered(ordered_ids)).ToList();
//////////////////////////////////////////////////
foreach (var item in OrderedData)
{
Console.WriteLine($"{item.Id} - {item.Title} - {item.ContactPerson } - {item.Keywords } - {item.Content }");
}
//////////////////////////////////////////////////
Console.ReadLine();
//////////////////////////////////////////////////
string getWhere(string _column, string _oprator)
{
var val = "Select Id From Orgs where ";
for (int i = 0; i < terms.Length; i++)
{
if (i > 0) val += @" " + _oprator + " ";
val += @" " + _column + " LIKE '%' + {" + i + "} +'%' ";
}
return val;
}
//////////////////////////////////////////////////
string getOrdered(int[] _ids_ordered)
{
var val = "Select * From Orgs where ";
val += " Id in ";
for (int i = 0; i < _ids_ordered.Length; i++)
{
if (i == 0) val += "( ";
if (i > 0) val += " , ";
val += _ids_ordered[i];
if (i == terms.Length - 1) val += " ) ";
}
val += " ORDER BY CASE id ";
for (int i = 0; i < _ids_ordered.Length; i++)
{
val += " WHEN " + _ids_ordered[i] + " THEN " + i;
}
val += " ELSE " + _ids_ordered.Length + " END ";
return val;
}
//////////////////////////////////////////////////
int[] reorderList(List<int> _Ids1, List<int> _Ids2,
List<int> _Ids3, List<int> _Ids4, List<int> _Ids5)
{
var idsDic = new Dictionary<int, int>();
var idsArr = new List<int>[5] { Ids1, Ids2, Ids3, Ids4, Ids5 };
for (int i = 0; i < 5; i++)
{
idsArr[i].ForEach(id =>
{
if (!idsDic.TryGetValue(id, out int val))
idsDic.Add(id, idsDic.Count());
});
};
var o_ids = idsDic.OrderByDescending(o => o.Value)
.Select(s => s.Key).ToArray();
return o_ids;
}
}
static Model1 db = new Model1();
static void Main(string[] args)
{
string search_quer = "Alcohol Support";
Console.WriteLine($"searching for {search_quer}");
search("Alcohol Support");
}
}
}
什么是Sql注入
SQL注入是一种代码注入技术,用于攻击 数据驱动的应用程序,其中包含恶意的SQL语句 插入要执行的输入字段
摘自Microsoft文档:How to: Directly Execute SQL Queries | Microsoft Docs
使用相同的参数在查询文本中表示 Console.WriteLine()和String.Format()使用的卷曲表示法。在 实际上,String.Format()实际上是在您查询的字符串上调用的 提供,将花括号参数替换为生成的 参数名称,例如@ p0,@ p1…,@ p(n)。
使用EF 6.2时
var sql2 = " Select Id From Orgs where ";
for (int i = 0; i < terms.Length; i++)
{
if (i > 0) sql2 += @" and ";
sql2 += @" Title LIKE '%' + {" + i + "} +'%' ";
}
将生成:
Select Id From Orgs where
Title LIKE '%' + {0} +'%'
and Title LIKE '%' + {1} +'%'
在使用 SQL Server Profiler
的sqlserver中exec sp_executesql N' Select Id From Orgs where
Title LIKE ''%'' + @p0 +''%'' and Title
LIKE ''%'' + @p1 +''%'' ',N'@p0 nvarchar(7)
,@p1 nvarchar(7)',@p0=N'Alcohol',@p1=N'Support'
我们还可以使用SqlParameter类
var sql4 = " Select Id From Orgs where ";
var sql4_parameter = new List<SqlParameter>();
for (int i = 0; i < terms.Length; i++)
{
if (i > 0) sql4 += @" or ";
sql4 += @" Keywords LIKE '%' + @param" + i + " +'%' ";
sql4_parameter.Add(new SqlParameter("param" + i, terms[i]));
}
这是sql
Select Id From Orgs
Where Keywords LIKE '%' + @param0 +'%'
or Keywords LIKE '%' + @param1 +'%'