【发布时间】:2017-02-03 00:11:55
【问题描述】:
我有一个存储地址的表。该表具有地址组件的多个字段,例如地址编号、街道名称、方向、后缀、前缀、城市、州和邮政编码。 (编辑:这个地址表有用户之前添加的地址。我希望他们来自同一个城镇、城市、州和国家。所以我确实保留了城市、州、国家和邮编来自他们,但不用于查询。)
我的应用程序是从数据库中用户输入的地址中找到完全匹配的地址。如果没有完全匹配,则返回相似的地址。
用户输入或存储在数据库中的所有地址均由 Google Map API 规范化以避免不匹配,例如 1234 N Johnson St、1234 North Johnson St 或 1234 North John Street。
这是我正在使用的完全匹配查询。由于存储和输入的地址均由 Google 地址 API 规范化,因此我得到了我想要的完全匹配结果。
var exactMatch = (from address in db.Addresses
where address.PrimaryAddressNumber == userInput.Number && address.Directional == userInput.Direction && address.Suffix == userInput.Suffix && address.StreetName == userInput.StreetName
select new IncidentSite
{
FullAddress = 'address components goes here'
});
但是,如果没有完全匹配,那么我想给用户一个选项。据我所知,构建多个查询然后组合在一起。它按我的预期工作,但时间太长了。
我正在做的事情
private IQueryable<IncidentSite> GetSimilarAddress(UserInput userInput)
{
var numberDirectionStreetname = (from address in db.Addresses
where address.PrimaryAddressNumber == userInput.Number && address.Directional == userInput.Direction && address.StreetName == userInput.StreetName
select new IncidentSite
{
FullAddress = 'address components goes here'
});
var numberStreetname = (from address in db.Addresses
where address.PrimaryAddressNumber == userInput.Number && address.StreetName == userInput.StreetName
select new IncidentSite
{
FullAddress = 'address components goes here'
});
var streetname = (from address in db.Addresses
where address.StreetName == userInput.StreetName
select new IncidentSite
{
FullAddress = 'address components goes here'
});
var similarAddress = numberDirectionStreetname.Union(numberStreetname).Union(streetname);
return similarAddress;
}
正如您在similarAdddress 看到的,它将运行来自dbo.Addresses 表的三个查询,但使用不同的where 语句,然后union 将所有三个结果构建一个结果。
我相信我正在做的不是找到类似地址的更聪明的方法。有什么好的方法可以让我构建一个更简单、更高效的查询吗?
编辑: 我想我不够清楚为什么我必须有三个不同的查询,而不是一个。原因是向用户提供所有可能的结果。为了更详细的解释,请看下文。
如果用户搜索“1234 North Johnson St”并且没有返回完全匹配,则执行以下步骤。
首先,numberDirectionStreetname,选择所有匹配“1234 North Johnson”的地址。所以结果可能是 1234 North Johnson + Boulevard/Street/Court/Way/Parkway/etc。我希望它显示在列表的顶部,因为存在的匹配地址组件比以下地址组件多。
其次,numberStreetname,选择所有匹配“1234 Johnson”的地址。所以结果可以是 1234 + South/North/East/West/etc + Johnson + Boulevard/Street/Court/Way/Parkway/etc
第三,街道名称,选择所有匹配“约翰逊”的地址。所以结果可以是 9999 + South/North/East/West/etc + Johnson + Boulevard/Street/Court/Way/Parkway/etc
如果可能,我想在一个查询中完成。这也是我的问题的一部分,不仅让它执行得更快,而且让它变得简单。但是,它必须是三个单独的查询,您将如何订购它们?如果我的逻辑不理想,那你会怎么建议?
【问题讨论】:
-
根据您的编辑 - 您已经足够清楚了。您想要与所提供地址的任何部分匹配的地址,并且地址与结果中排序较高的大多数部分匹配。为此,您不需要 3 个单独的查询。有关在一个查询中完成此操作的方法,请参见下面的答案。顺便说一句,虽然你没有要求,但如果你想让某些部分的匹配比其他部分更重要,你只需要加权该部分的排名即可。
-
谢谢!我阅读了您的答案并致力于我的项目以使其按计划执行。我知道你理解我的问题,但是我不得不添加更多细节,因为对方问了。
-
很高兴它有帮助。
标签: c# sql-server linq kendo-grid