Azure 搜索 return 父子记录
Azure search return parent and child records
我们的应用程序管理用户拥有的书籍,其中一本书包含多个文档(pdf、word 文档等)。主页列出了用户的所有书籍,并带有一个用于加载下 10 本书的分页按钮。然后,当用户单击一本书时,它会在新屏幕中打开并列出该书的所有文档。
到目前为止,我们使用 WCF / entity framework 检索主页上显示的所有书籍,然后使用 Azure 搜索(连接到 sql 视图)获取一本书的文档它被打开,与分页和排序一起工作得很好。
现在虽然我们还想从 Azure 搜索中获取用户的所有书籍列表,因此我们创建了一个新的 table 来保存书籍和文档数据,每个文档一行表示父书籍名称并且每行重复书籍 ID。
AzureSearchTable
我们的 azure 搜索索引现在指向此 table,我必须弄清楚如何通过分页和可能的排序为用户检索书籍。
问题是我需要一个独特的 select 用于书籍,但 azure 搜索不区分,我不知道一本书可能有多少文档,所以我不能将 Top 参数设置为 10。一本书可能有 30 或 40 个文档,这意味着前 40 行可能只用于一本书。
我尝试在图书 id 上使用一个 facet,哪种方法有效,并为我提供了每本书的 id 和文档数量,但我似乎无法为该 facet 指定排序顺序 - 顺序是与我为查询 (BookId) 设置的顺序不同。我也不知道如何使用 facet 获取所有书籍 - 我可以在 facet 上设置计数 属性 但我不知道用户将拥有多少本书。
我们的架构师说我应该获取所有行(可能有数千行)并在 C# 代码中过滤它们以获得 10 本书。不过,这对我来说似乎效率很低,而且感觉不对。
所以我不确定这是否是正确的方法..
- 我应该为书籍和文档数据设置单独的 Azure 搜索索引(使用单独的 tables 吗?
- 如何在不知道每本书有多少文档的情况下return这本 table 的前 n 本书?
- 我可以使用 C# sdk 为构面指定排序顺序吗? (我认为通过其余的 API 是可能的)
- 如何获取某个用户的 return 所有书籍的分面?
这里有一些想法:
项目符号 #1 答案:
如果您的意图是能够return 基于对 DocumentName 的搜索的图书列表,那么您可能希望将它们保存在同一个索引中。您的架构师关于在 C# 中处理结果的想法可能并不像您想象的那么糟糕。您可以在 LINQ 中执行 GroupBy。 Azure 搜索查询很快,LINQ 查询也很快。特别是如果发出 Azure 搜索查询的机器是 Azure web/app 服务器并且位于同一区域(数据中心内通信)。我已经将这种方法与建议 API 一起用于自动完成功能,该功能需要在用户输入时快速(在几百毫秒内)得到 return 结果。我想说至少值得一试,看看您在最大和典型数据集上获得了什么样的性能。
但是,如果这对您不起作用,请考虑重新构建您的索引架构,使 DocumentName 的类型为 Collection(Edm.String)。你看起来像这样:
{
id: 20663,
userId: 1,
bookId: 2144,
bookName: "ber",
documentName: ["asdasd", "_318-1991.jpg", "wallhaven-13081.png", etc...],
documentCount: 7
}
现在,如果您需要允许用户获取有关他们 select 的特定书籍文档的详细信息,您只需调用数据库来获取书籍详细信息即可。或者,您可以在此处可以 为具有更详细文档信息的文档创建另一个 Azure 搜索索引。但是在用户工作流的这一点上,除非您打算在该特定书籍的文档中提供另一个全文搜索,否则您可能只想坚持使用 get-by-id 类型的数据库调用。
项目符号 #2 答案:
对于文档计数,您可以创建另一个字段(如上所示)并在其上 sort/filter/facet。
项目符号 #3 答案:
SDK 和 Azure Search REST API 均未提供对构面本身进行排序的方法,但请记住,您最终可以完全控制要在 [=60= 中显示构面信息的方式].如果 SDK 没有提供您需要的内容,您可以在您的应用程序中创建一个简单的查找 class 以根据需要对您的构面进行排序。像这样:
public class FacetDefinition
{
public string FacetName { get; set; }
public int FacetOrder { get; set; }
}
...
var myFacetDefinitions = new List<FacetDefinition>();
myFacetDefinitions.Add(new FacetDefinition() { FacetName = "SomeNameThatMatchesTheFacetThatAzureSearchSendsBack", FacetOrder = 1});
myFacetDefinitions.Add(new FacetDefinition() { FacetName = "SomeOtherNameThatMatchesTheFacetThatAzureSearchSendsBack", FacetOrder = 2});
...
项目符号 #4 答案:
要return 特定用户的所有书籍,您只需添加一个过滤器表达式,如下所示:
userId eq <put_authenticated_userid_here>
这是假设当前经过身份验证的用户应该只能看到他们自己的书。但是,如果您希望能够在一个方面拥有一个用户列表以过滤其中的一个或多个用户,那么这将需要对索引模式进行另一次重构,以便在书籍文档上有一个名为类似的新字段"users" 是用户名的集合(Edm.String)。像这样:
{
...
users: ["Luke Skywalker", "Han Solo", "Chewbacca", etc...]
...
}
我们的应用程序管理用户拥有的书籍,其中一本书包含多个文档(pdf、word 文档等)。主页列出了用户的所有书籍,并带有一个用于加载下 10 本书的分页按钮。然后,当用户单击一本书时,它会在新屏幕中打开并列出该书的所有文档。
到目前为止,我们使用 WCF / entity framework 检索主页上显示的所有书籍,然后使用 Azure 搜索(连接到 sql 视图)获取一本书的文档它被打开,与分页和排序一起工作得很好。
现在虽然我们还想从 Azure 搜索中获取用户的所有书籍列表,因此我们创建了一个新的 table 来保存书籍和文档数据,每个文档一行表示父书籍名称并且每行重复书籍 ID。
AzureSearchTable
我们的 azure 搜索索引现在指向此 table,我必须弄清楚如何通过分页和可能的排序为用户检索书籍。 问题是我需要一个独特的 select 用于书籍,但 azure 搜索不区分,我不知道一本书可能有多少文档,所以我不能将 Top 参数设置为 10。一本书可能有 30 或 40 个文档,这意味着前 40 行可能只用于一本书。
我尝试在图书 id 上使用一个 facet,哪种方法有效,并为我提供了每本书的 id 和文档数量,但我似乎无法为该 facet 指定排序顺序 - 顺序是与我为查询 (BookId) 设置的顺序不同。我也不知道如何使用 facet 获取所有书籍 - 我可以在 facet 上设置计数 属性 但我不知道用户将拥有多少本书。
我们的架构师说我应该获取所有行(可能有数千行)并在 C# 代码中过滤它们以获得 10 本书。不过,这对我来说似乎效率很低,而且感觉不对。
所以我不确定这是否是正确的方法..
- 我应该为书籍和文档数据设置单独的 Azure 搜索索引(使用单独的 tables 吗?
- 如何在不知道每本书有多少文档的情况下return这本 table 的前 n 本书?
- 我可以使用 C# sdk 为构面指定排序顺序吗? (我认为通过其余的 API 是可能的)
- 如何获取某个用户的 return 所有书籍的分面?
这里有一些想法:
项目符号 #1 答案:
如果您的意图是能够return 基于对 DocumentName 的搜索的图书列表,那么您可能希望将它们保存在同一个索引中。您的架构师关于在 C# 中处理结果的想法可能并不像您想象的那么糟糕。您可以在 LINQ 中执行 GroupBy。 Azure 搜索查询很快,LINQ 查询也很快。特别是如果发出 Azure 搜索查询的机器是 Azure web/app 服务器并且位于同一区域(数据中心内通信)。我已经将这种方法与建议 API 一起用于自动完成功能,该功能需要在用户输入时快速(在几百毫秒内)得到 return 结果。我想说至少值得一试,看看您在最大和典型数据集上获得了什么样的性能。
但是,如果这对您不起作用,请考虑重新构建您的索引架构,使 DocumentName 的类型为 Collection(Edm.String)。你看起来像这样:
{
id: 20663,
userId: 1,
bookId: 2144,
bookName: "ber",
documentName: ["asdasd", "_318-1991.jpg", "wallhaven-13081.png", etc...],
documentCount: 7
}
现在,如果您需要允许用户获取有关他们 select 的特定书籍文档的详细信息,您只需调用数据库来获取书籍详细信息即可。或者,您可以在此处可以 为具有更详细文档信息的文档创建另一个 Azure 搜索索引。但是在用户工作流的这一点上,除非您打算在该特定书籍的文档中提供另一个全文搜索,否则您可能只想坚持使用 get-by-id 类型的数据库调用。
项目符号 #2 答案:
对于文档计数,您可以创建另一个字段(如上所示)并在其上 sort/filter/facet。
项目符号 #3 答案:
SDK 和 Azure Search REST API 均未提供对构面本身进行排序的方法,但请记住,您最终可以完全控制要在 [=60= 中显示构面信息的方式].如果 SDK 没有提供您需要的内容,您可以在您的应用程序中创建一个简单的查找 class 以根据需要对您的构面进行排序。像这样:
public class FacetDefinition
{
public string FacetName { get; set; }
public int FacetOrder { get; set; }
}
...
var myFacetDefinitions = new List<FacetDefinition>();
myFacetDefinitions.Add(new FacetDefinition() { FacetName = "SomeNameThatMatchesTheFacetThatAzureSearchSendsBack", FacetOrder = 1});
myFacetDefinitions.Add(new FacetDefinition() { FacetName = "SomeOtherNameThatMatchesTheFacetThatAzureSearchSendsBack", FacetOrder = 2});
...
项目符号 #4 答案:
要return 特定用户的所有书籍,您只需添加一个过滤器表达式,如下所示:
userId eq <put_authenticated_userid_here>
这是假设当前经过身份验证的用户应该只能看到他们自己的书。但是,如果您希望能够在一个方面拥有一个用户列表以过滤其中的一个或多个用户,那么这将需要对索引模式进行另一次重构,以便在书籍文档上有一个名为类似的新字段"users" 是用户名的集合(Edm.String)。像这样:
{
...
users: ["Luke Skywalker", "Han Solo", "Chewbacca", etc...]
...
}