首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按相关性/等级排序搜索结果

按相关性/等级排序搜索结果
EN

Stack Overflow用户
提问于 2019-01-07 12:07:28
回答 1查看 914关注 0票数 3

我在.net中创建了一个C# MVC应用程序,其中列出了组织,目前数据库中有6000条记录(SQLServer)。组织表中的字段是:

  • 头衔(酒精支持小组)
  • ContactPerson (詹姆斯·邦德)
  • 内容(我们为有酒精问题的人提供支持)
  • 关键词(酒精、成瘾、酒精)

当前的搜索是使用linq完成的,例如:

代码语言:javascript
复制
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();

然后将结果按标题排序。这不合适。

如果有人搜索‘酒精支持’,我希望上面的结果在列表的首位。

我希望将结果按以下顺序排列:

  1. 组织名称中的完整句子匹配。
  2. 所有组织名称中的搜索词。
  3. 任何组织名称中的搜索词。
  4. 任何组织关键字中的搜索词。
  5. 完整的句子与组织内容相匹配。

寻找实现这一点的最佳方法的建议,或者如果有人知道有任何算法/库已经这样做了?

**更新**我现在正在寻找一个更简单的解决方案,请参阅以下链接:

基于Linq关键字的排序集合

EN

回答 1

Stack Overflow用户

发布于 2019-01-07 17:54:46

摘要:

  • 要求的
代码语言:javascript
复制
- R01 | titles   | Full matches |in order
- R02 | titles   | Full matches |in any  order
- R03 | titles   | Any matches  |
- R04 | keywords | Any matches  |
- R05 | content  | Full matches | 

  • 对于每个需求,我们将执行SQL调用
  • 每个SQl调用只返回id的行
  • 然后我们把Id按顺序分组
  • 我们将进行最后的SQL调用。

步骤01 : R01

  • 在这里我们将使用EF db.Orgs.Where(w => w.Title.Contains(search_query)) .Select(s => s.Id).ToList()

linq2Sql 包含的这种用法将被转换为sql IN

第二步: R02

  • 这里我们将使用普通的sql ,其中+,如+ 从Orgs中选择Id,其中标题为'%‘+ @param0 0 +'%’,标题为'%‘+@param0 1 +'%’。

步骤03 : R03

  • 这里我们将使用普通的sql ,其中++ 从标题如'%‘+ @param0 0 +'%’或标题类似于'%‘+@陷落1 +'%’的Orgs中选择Id

第04步: R04

  • 这里我们将使用普通的sql ,其中++ 从关键字'%‘+ @param0 0 +'%’或关键字'%‘+@氢1 +'%’中选择Id。

第05步: R05

  • 在这里我们将使用EF db.Orgs .Where(w => w.Content.Contains(search_query))。选择(s => s.Id).ToList();

linq2Sql 包含的这种用法将被转换为sql IN

步骤06 -将Id分组,忽略可复制的Id

  • 使用行id的表单步骤1至5

我们将根据订单检索对id的基础进行排序

代码语言:javascript
复制
        var ids = new Dictionary<int, int>();

        foreach (var id in Ids1)
        {
            int val;
            if (!ids.TryGetValue(id, out val))
            {
                ids.Add(id, ids.Count());
            }

        };
        .
        .

第07步-重新订购

代码语言:javascript
复制
         ids.OrderByDescending(o => o.Value)
        .Select(s => s.Key) .ToArray();

步骤08 -现在我们使用Oredred Id来获取数据

  • 在这里,我们将使用普通sql ORDER BY +大小写,然后结束。 从(2,1)中的Id按大小写顺序选择*,当2,然后0,当1,2结束时

第09步完整代码

代码语言:javascript
复制
    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");
    }
    }


    }

注01 : Sql注入

  • 什么是Sql注入? SQL注入是一种代码注入技术,用于攻击数据驱动的应用程序,其中邪恶的SQL语句被插入到入口字段中执行。

注01.01 :问题

注01.02 : Microsoft文档

  • 来自Microsoft文档:如何:直接执行SQL查询 参数通过使用Console.WriteLine()和String.Format()使用的相同的卷曲表示法在查询文本中表示。实际上,在您提供的查询字符串上实际上调用了String.Format(),用生成的参数名(如@p0,@p1…)替换了带大括号的参数,@p(n)。

注01.03 :在本项目中

  • 使用EF 6.2时 变量sql2 =“从其中选择Id ";对于(int i= 0;i< terms.Length;i++) { if (i > 0) sql2 += @和";sql2 += @”标题,如'%‘+ {“+i+ "} +'%’};
  • 将产生: 从“%”+ {0} +“%”的标题和“%”+ {1} +'%‘的标题中选择Id
  • 在sqlserver中使用sqlserver事件探查器 执行sp_executesql N‘从标题“%”+ @p0 +“%”和标题“%”+ @p1 +“%”、N'@p0 nvarchar(7)、@p1 nvarchar(7)、@P0= N’酒精‘、@p1=N’‘Support’的Orgs中选择Id

注01.04 :另一种格式

  • 我们也可以使用SqlParameter类 var sql4 =“从其中选择Id ";var sql4_parameter =新列表();for (int i= 0;i< terms.Length;i++) { if (i > 0) sql4 += @或";sql4 += @”关键字,如'%‘+ @param“+i+”+'%’;sql4_parameter.Add(“param”+ i,termsi)}};
  • 这是sql 从关键字'%‘+ @param0 0 +'%’或关键字'%‘+@氢1 +'%’中选择Id。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54074142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档