此文章由机器翻译。
Microsoft Azure
通过 Azure 搜索增强数据挖掘功能
数据探索、 实时分析和机器学习等领域都被应用于许多创造性的方式。公司正在建设围绕开放源码软件包各种有趣的架构。蔚蓝的搜索是这样一块更大的体系结构。蔚蓝的搜索是一个强大的新的搜索体验,为您的 Web 站点和应用程序 — — 即使你不是一个搜索专家。
蔚蓝的搜索是一个使用简单的 REST API 的完全托管的、 基于云计算的服务。它包括类型前面的建议,建议的结果接近匹配、 多方位的导航和基于需要的能力的适应能力的基础。蔚蓝搜索提供全文本搜索与权重、 排名和您自己的搜索行为基于由 field 属性组合定义的架构。数据立即建立索引,这最小化搜索延迟。
有效的搜索需要越来越规模庞大的数据存储区。在 facebook 上独自,用户花了数以亿计的分钟搜索每个月。要有效地搜索维基百科,将索引 1700 万条目。Twitter 拥有超过 6 亿用户,生成 = 每天超过 50,000 的推文。执行这种规模的全文本搜索需要一些创造性的工程。索引和牧师所有这信息并不适合胆小的心。
对于哪个搜索引擎是其业务的一个组成部分的许多公司正着手与 Azure G 系列虚拟机使用 32 个内核,448 GB RAM 和 6.5 TB 的固态驱动器 (SSD)。有些工程师正在编写自定义程序集和 C 代码来优化缓存一致性的数据和指令缓存。他们使用缓存来减少所用的时间的 CPU 的坐在那里等待内存请求履行,并减少需要传输的数据总量。在这些巨大的、 多核的机器内的一个挑战是有多个线程争夺内存总线。 利用 L2 和 L3 高速缓存的性能提升是数量级的顺序更有意义。这一切很重要,因为大量的数据快速进入你的全文搜索引擎是关键。
全文本搜索做得正确
蔚蓝的搜索提供了许多优势。它减少了复杂的设置和管理您自己的搜索索引。它是完全托管的服务,帮助您避免麻烦,处理索引损坏、 服务可用性、 缩放和服务的更新。大的优点之一是 Azure 搜索支持丰富、 精确的排序模型。这允许您绑到业务目标的搜索结果。它还提供多语言搜索、 拼写错误校正及类型前面的建议。如果搜索结果很薄弱,Azure 搜索可以建议查询基于接近的匹配项。你可以在资源调配新的 Azure 搜索实例在快速的教程 bit.ly/1wYb8L8。
本教程将引导你通过入门,你需要在门户网站执行的步骤。你会提供 Azure Azure 管理门户中搜索 (portal.azure.com),这需要两件事情:通过门户网站提供的 URL,本身和 API 密钥。URL 表示在云中运行您的客户端应用程序将谈谈你 Azure 搜索服务端点。API 密钥将需要小心,保护因为它提供了所有的访问到您的服务。毕竟,你不能允许任何客户端访问 Azure 搜索服务而无需经过身份验证与此键。
有限制和约束的你应该意识到在索引,每个索引的最大字段的数目,最大文档数量,等等。一个重要的限制是有未获配额或与查询相关联的最高限额。查询每秒 (检疫) 是可变的具体取决于可用带宽和系统资源的竞争。
用免费的 Azure 搜索服务,蔚蓝的计算和存储资源支持您共享的服务由多个订阅服务器,共享,所以检疫为您的解决方案将取决于有多少工作负载运行在同一时间。专用 (标准 SKU 的) 服务,全部奉献给客户和资源不能共享。
一旦你有你的 URL 和 API 密匙,你准备好要使用这项服务。最简单的方式做到这一点是提琴手,因为它可以让您撰写自己的 HTTP 请求。(得到一份免费的提琴手在 bit.ly/1jKA1UJ.)蔚蓝搜索使用简单的 HTTP,所以很琐碎与提琴手的插入和查询数据 (请参阅图 1)。后来在这篇文章,你会看到如何使用 Node.js 谈谈 Azure 搜索。
图 1 执行插入到 Azure 搜索使用提琴手
正如你所看到的有四样东西用来担心自己:
- HTTP 谓词
- URL
- 请求标头
- 请求页脚
HTTP 谓词 (放、 发布、 获取或删除) 映射到不同的操作,是否架构定义操作、 数据插入操作等等。举个例子,把地图放到架构定义和邮政将映射到数据插入操作。可用从 Azure 门户 URL 并可能随您的查询参数。在请求标头中发送,API 密钥。请求正文始终是一个 JSON 表示架构或数据被插入。
蔚蓝的搜索可以发挥更大体系结构中的关键作用。图 2 演示利用 Azure 搜索架构。开头的基本身份验证层,在那里你有一些选项。例如,您可以使用 Azure 活动目录图形 API 与 Node.js 使用 OAuth2。 谈到 Node.js,你可以使用它作为 URL 的 Azure 搜索,提供一些结构和控制对您的服务终结点的代理。
图 2 蔚蓝搜索更大体系结构中
Azure 搜索的最显著特性之一是你可以索引和搜索几乎任何结构化的数据 — — 除了照片、 图像和视频。图 2 Azure 搜索说明某些潜在的数据源。由于关系数据库并不适合于执行全文搜索,很多初创公司及其关系的数据,将关键的数据导出到 Azure 搜索。这也是有益的因为它可以在关系数据库中进行全文搜索的负担。
这并不意味着 Azure 搜索是结束所有,或者是所有。您仍然需要排雷数据使用 Hadoop 或 HDInsight 地图/减少科技应用机器学习的算法,聚类,如文本文档分为局部相关文件。
想象一下分析一条 tweet,给它一个分数的可能性有多大,它属于一些其他类别中。例如,您可能有一个类别的演说呼吁充满感情的批评或另一种称为叫嚷积极发表意见。线性分类器算法通常用于这种洞察力。蔚蓝的搜索并不是有这个能力。但是想象一下你在 Azure 搜索文档编制索引的方式基于你进行分类和分析数据的方式。
Node.js
现在我会把我的注意力转向写作 Node.js 的前端,以会为在 Azure 搜索代理层。
- 第 1 步要求您完成早些时候在这篇文章指出,以致 Azure 搜索设置在门户获得入门的教程。还记得你需要的 URL 和 API 密钥。
- 第 2 步要求您下载并在您的开发计算机上本地安装 Node.js 运行时。你可以在 nodejs.org/download 找到这。我安装文件夹 c:\program files\nodejs 以告终。它被推荐给你一个基本的"你好世界"在进一步行动之前在 Node.js 运行。
- 第 3 步要求您确认节点软件包管理器 (NPM) 上正确安装和配置。新公共管理允许您在故宫注册表上安装 Node.js 应用 (JavaScript)。
- 第 4 步涉及安装 elasticsearch 软件包,简化了编写代码与 Azure 搜索进行通信。
一旦你完成了这些步骤,你准备好要返回到命令提示符处,导航到任何你喜欢的目录和开始编写代码。如果您遇到与故宫的一些错误,您可能需要验证某些环境变量:
C:\node>set nodejs=C:\Program Files\nodejs\
C:\node>set node_path=C:\Program Files\nodejs\node_modules\*
C:\node>set npm=C:\Program Files\nodejs\
打造出了 Node.js 解决方案
现在你准备好要开发一些 Node.js 代码来在您的本地系统来说明沟通 Azure 搜索上执行。Node.js 在 Azure 搜索使得它易于插入和查询数据。假设您有 terkaly.search.windows.net Azure 搜索 URL。 你会从 Azure 管理门户。你还需要您的 API 密钥,本例中是 B7D12B8CA3D018EC09C754F95CA552D2。
有不止一种方法来开发 Node.js 应用程序在您的本地计算机上。如果你爱在 Visual Studio 调试器,然后就会想要用于 Visual Studio 插件的 Node.js 工具 (nodejstools.codeplex.com)。如果你喜欢命令行,请查阅 Nodejs.org。 一旦你安装 Node.js,是重要的是整合故宫。这允许您在故宫注册表上安装 Node.js 应用程序可用。在这里使用的核心封装调用请求。
中的代码图 3 是简单的。它做同样的事情,如在本教程中所述 bit.ly/1Ilh6vB,唯一的区别在于你已经实现了此代码和 Node.js 使用请求包。代码覆盖了一些更通用的用例,如创建索引,将数据插入和,当然,执行查询。有很多回调定义架构,插入数据和查询数据。
图 3 Node.js 代码,以演示如何创建一个索引,将数据插入和查询数据
var request = require('request');
//////////////////////////////////////////////////
// OPTIONS FOR HTTP PUT
// Purpose: Used to create an index called hotels
//////////////////////////////////////////////////
var optionsPUT = {
url: 'https://terkaly.search.windows.net/indexes/hotels?api-version=2014-07-31-Preview',
method: 'PUT',
json: true,
headers: {
'api-key': 'B7D12B8CA3D018EC09C754F95CA552D2',
'Content-Type': 'application/json'
},
body: {
"name": "hotels",
"fields": [
{ "name": "hotelId", "type": "Edm.String", "key": true, "searchable": false },
{ "name": "baseRate", "type": "Edm.Double" },
{ "name": "description", "type": "Edm.String", "filterable": false,
"sortable": false,
"facetable": false, "suggestions": true },
{ "name": "hotelName", "type": "Edm.String", "suggestions": true },
{ "name": "category", "type": "Edm.String" },
{ "name": "tags", "type": "Collection(Edm.String)" },
{ "name": "parkingIncluded", "type": "Edm.Boolean" },
{ "name": "smokingAllowed", "type": "Edm.Boolean" },
{ "name": "lastRenovationDate", "type": "Edm.DateTimeOffset" },
{ "name": "rating", "type": "Edm.Int32" },
{ "name": "location", "type": "Edm.GeographyPoint" }
]
}
};
//////////////////////////////////////////////////
// OPTIONS FOR HTTP POST
// Purpose: Used to insert data
//////////////////////////////////////////////////
var optionsPOST = {
url: 'https://terkaly.search.windows.net/indexes/hotels/docs/
index?api-version=2014-07-31-Preview',
method: 'POST',
json: true,
headers: {
'api-key': 'B7D12B8CA3D018EC09C754F95CA552D2',
'Content-Type': 'application/json'
},
body: {
"value": [
{
"@search.action": "upload",
"hotelId": "1",
"baseRate": 199.0,
"description": "Best hotel in town",
"hotelName": "Fancy Stay",
"category": "Luxury",
"tags": ["pool", "view", "wifi", "concierge"],
"parkingIncluded": false,
"smokingAllowed": false,
"lastRenovationDate": "2010-06-27T00:00:00Z",
"rating": 5,
"location": { "type": "Point", "coordinates": [-122.131577, 47.678581] }
},
{
"@search.action": "upload",
"hotelId": "2",
"baseRate": 79.99,
"description": "Cheapest hotel in town",
"hotelName": "Roach Motel",
"category": "Budget",
"tags": ["motel", "budget"],
"parkingIncluded": true,
"smokingAllowed": true,
"lastRenovationDate": "1982-04-28T00:00:00Z",
"rating": 1,
"location": { "type": "Point", "coordinates": [-122.131577, 49.678581] }
},
{
"@search.action": "upload",
"hotelId": "3",
"baseRate": 279.99,
"description": "Surprisingly expensive",
"hotelName": "Dew Drop Inn",
"category": "Bed and Breakfast",
"tags": ["charming", "quaint"],
"parkingIncluded": true,
"smokingAllowed": false,
"lastRenovationDate": null,
"rating": 4,
"location": { "type": "Point", "coordinates": [-122.33207, 47.60621] }
},
{
"@search.action": "upload",
"hotelId": "4",
"baseRate": 220.00,
"description": "This could be the one",
"hotelName": "A Hotel for Everyone",
"category": "Basic hotel",
"tags": ["pool", "wifi"],
"parkingIncluded": true,
"smokingAllowed": false,
"lastRenovationDate": null,
"rating": 4,
"location": { "type": "Point", "coordinates": [-122.12151, 47.67399] }
}
]
}
};
//////////////////////////////////////////////////
// OPTIONS FOR HTTP GET
// Purpose: Used to do a perform a query
//////////////////////////////////////////////////
var optionsGET = {
url: 'https://terkaly.search.windows.net/indexes/hotels/
docs?search=motel&facet=category&facet=rating,
values:1|2|3|4|5&api-version=2014-07-31-Preview',
method: 'GET',
json: true,
headers: {
'api-key': 'B7D12B8CA3D018EC09C754F95CA552D2',
'Content-Type': 'application/json'
},
body: {
}
};
request(optionsPUT, callbackPUT);
//////////////////////////////////////////////////
// Purpose: Used to create an index
// Http Verb: PUT
// End Result: Defines an index using the fields
// that make up the index definition.
//////////////////////////////////////////////////
function callbackPUT(error, response, body) {
if (!error) {
try {
if (response.statusCode === 204) {
console.log('***success in callbackPUT***');
request(optionsPOST, callbackPOST);
}
} catch (error2) {
console.log('***Error encountered***');
console.log(error2);
}
} else {
console.log('error');
console.log(error);
}
}
//////////////////////////////////////////////////
// Purpose: Used to insert data
// End Result: Inserts a document
//////////////////////////////////////////////////
function callbackPOST(error, response, body) {
if (!error) {
try {
var result = response.request.response.statusCode;
if (result === 200) {
console.log('***success in callbackPOST***');
console.log("The statusCode = " + result);
// Perform a query
request(optionsGET, callbackGET);
}
} catch (error2) {
console.log('***Error encountered***');
console.log(error2);
}
} else {
console.log('error');
console.log(error);
}
}
//////////////////////////////////////////////////////////////
// Purpose: Used to retrieve information
// Http Verb: GET
// End Result: Query searches on the term "motel" and retrieves
// facet categories for ratings.
//////////////////////////////////////////////////////////////
function callbackGET(error, response, body) {
if (!error) {
try {
var result = response.request.response.statusCode;
if (result === 200) {
result = body.value[0];
console.log('description = ' + result.description);
console.log('hotel name = ' + result.hotelName);
console.log('hotel rate = ' + result.baseRate);
}
console.log('***success***');
} catch (error2) {
console.log('***Error encountered***');
console.log(error2);
}
} else {
console.log('error');
console.log(error);
}
}
回调链是直截了当的以及。它以简单的 GET 开头,然后移动到付诸表决,邮政和第二次获得 (和查询)。它表明你会用 Azure 搜索的核心业务。首先,创建的文档后,您将添加架构的。使用 PUT HTTP 动词来定义的架构。接下来,使用后插入数据。最后,使用 GET 查询数据。
总结
在这篇文章的目标是使一些初创企业,特别是在社会网络分析领域的世界外面发生的激动人心的事情。你可以使用 Azure 搜索作为一块更大的解决方案中,您需要一个复杂和强大的搜索体验,与您的 Web 站点和应用程序进行集成。它允许您使用微调的排名模型以配合业务目标,以及可靠的吞吐量和存储的搜索结果。
Bruno Terkaly 是主要软件工程师在微软,目的是发展的业界领先的应用程序和服务启用跨设备。他是负责开车穿越美国的顶级云计算和移动的机会和从技术支持的角度之外。他帮助合作伙伴带来市场及其应用提供建筑指导和深厚的技术接合 ISV 的评价、 开发和部署过程。他还密切与云计算和移动工程群体、 提供反馈和影响路线图 》。
衷心感谢以下 Microsoft 技术专家对本文的审阅:利亚姆 · 卡瓦纳,Simon Gurevich,戈文德坎、 拉吉克里希南,一些 Latchupatula,Eugene 什韦茨