【问题标题】:How to deal with text input containing a last name with a space or a first name [space] last name combination如何处理包含姓氏和空格或名字[空格]姓氏组合的文本输入
【发布时间】:2015-05-28 22:29:17
【问题描述】:

我正在处理一个我无法解决的问题,可以使用您的帮助和专业知识。

我有一个文本框,允许用户通过下面列出的名称标准组合搜索另一个用户:

  • 名字>空格>姓>(约翰·史密斯)
  • 姓>逗号>空格|nospace>名字>(史密斯, John) 或 (Smith,John)
  • 名字或姓氏的起始部分(在本例中,我同时搜索名字和姓氏列)(Smith)、(John)、(Sm) 或 (Jo)

问题: 有不少用户的姓氏中有空格,如果有人搜索他们,他们可能只会输入“de la”。

现在在这种情况下,由于单词之间有空格,系统将假定搜索条件是名字以“de”开头,姓氏以“la”。 如果用户键入“de la,”,系统将按预期工作,因为现在输入包含逗号,系统将确定此搜索是针对姓氏的,但我必须假设不是每个人都会在末尾输入逗号。

但是,用户可能只想搜索姓氏以“de la”开头的人。

当前选项 我有几个选择,可以使用您的帮助来决定您推荐哪一个。请随时添加您的建议。

  • 用户培训。我们始终可以创建帮助指南/培训材料,以建议用户在搜索包含空格的姓氏时在末尾输入逗号。我不喜欢这种方法,因为用户体验不再智能/直观,而且大多数用户不会阅读帮助指南。
  • 创建 2 个不同的文本框(用于名字和姓氏)。我也不喜欢这种方法。 UI 的外观和感觉都不一样,对于只想从 Outlook 或其他地方复制/粘贴名称(无需单独复制/粘贴名字/姓氏)的用户来说,这会带来不便。

  • 首先运行搜索条件,然后再运行搜索具有间隔姓氏的人,并将两个结果附加到返回值。这可能有效,但会产生大量误报并导致服务器额外负载。例如。搜索“de la”将返回 Lance, Devon (...) 和“De La Cruz, John” (...) .

如果您能就此问题提供任何类型的反馈,我将不胜感激;您的经验、最佳实践或最佳实践,即您使用过的与此场景相关的一些代码 sn-ps。

应用背景:其用C#编写的ASP.NET (4.0) WebAPI服务;它由位于不同服务器上的客户端使用。

【问题讨论】:

  • 正则表达式将是一个好的开始。
  • 你能给我一个例子,在这种情况下正则表达式会有所帮助吗?我已经在使用正则表达式来检查空格/逗号等,并且愿意接受任何新想法。
  • 你可以使用(([a-zA-Z-']+)\s?([a-zA-Z-' ]+)+|([a-zA-Z-' ]+)(\s?,\s?|\s)([a-zA-Z-' ]+))之类的东西。在 regexr.com 上使用它。

标签: c# search asp.net-web-api


【解决方案1】:

我已经使用这种技术很多年了,我喜欢它。

丢掉逗号,没人会用。如果没有空格,则搜索 first OR last。如果有空格,则搜索 first AND last。此代码非常适合部分名称搜索,即“JS”查找 Jane Smith 和 John Smith。 “John”将找到“John Smith”和“Anne Johnson”。这应该为您提供一个很好的起点,让您可以随心所欲地使用受支持的查询。

public IEnumerable<People> Search(string query, int maxResults = 20)
{
    if (string.IsNullOrWhiteSpace(query))
    {
        return new List<People>();
    }

    IEnumerable<People> results;

    var split = query.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

    if (split.Length > 1)
    {
        var firstName = split[0];
        var lastName = string.Join(" ", split.Skip(1));

        results = PeopleRepository.Where(x => 
            x.FirstName.StartsWith(firstName, StringComparison.OrdinalIgnoreCase) &&
            x.LastName.StartsWith(lastName, StringComparison.OrdinalIgnoreCase));
    }
    else
    {
        var search = split[0];
        results = PeopleRepository.Where(x => 
            x.FirstName.StartsWith(search, StringComparison.OrdinalIgnoreCase) ||
            x.LastName.StartsWith(search, StringComparison.OrdinalIgnoreCase));
    }

    return results.Take(maxResults);
}

【讨论】:

  • 您可以使用我找到的扩展名 here 处理 LastName FirstName 搜索。 ...var lastName = ... var altFirstName = split[split.Count() - 1] var altLastName = string.Join(" ", split.AllButLast())... .Where(... (x.FirstName.... &amp;&amp; x.LastName...) || (x.FirstName.StartsWith(altFirstName... x.LastName.StartsWith(altLastName...) 不适用于包含空格的复杂名字。
【解决方案2】:

也许关键是您应该索引您的用户数据以便有效地查找它。

例如,您应该为名字和姓氏编制索引,而不用关心它们是名字还是姓氏。你想搜索人,为什么最终用户要关心搜索词的顺序?

整个索引可以将用户 ID 存储在按名称(名字或姓氏)专门化的集合上。如果用户 ID 是整数,则如下所示:

John => 12, 19, 1929, 349, 1, 29
Smith => 12, 349, 11, 4
Matias => 931, 45
Fidemraizer => 931

这样用户输入任何内容,您不再关心排序:如果用户键入“John”,您将向所有用户显示他们的 ID 在 John 集中的位置。如果他们同时输入 John Smith,您需要将 JohnSmith 集合相交以找出两个集合中都有哪些用户 ID,依此类推。

我不知道您目前使用的是什么数据库技术,但 SQL 和 NoSQL 产品都可以很好地存储,但 NoSQL 会更好。

【讨论】:

  • 谢谢马蒂亚斯。我一回家就试一试;刚下班就看到了。
猜你喜欢
  • 1970-01-01
  • 2014-11-03
  • 2016-02-22
  • 2013-10-08
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多