2017-05-06 43 views
3

我们的应用程序管理用户拥有的图书,其中包含多个文档(pdf,word文档等)。主页列出了用户的所有书籍以及用于分页的按钮,用于加载下10本书。然后,当用户点击一本书时,它会在新屏幕中打开并列出该书的所有文档。Azure搜索返回父母和子女记录

到目前为止,我们使用WCF /实体框架来检索主页上显示的所有图书,然后天蓝色的搜索(连接到一个sql视图)获取一本书在打开时的文档,分页和排序。

现在,尽管我们也想从azure搜索中获取用户的所有书籍的列表,所以我们创建了一个新表来存放图书和文档数据,每个文档一行表示父书名和书籍ID被重复为每一行。

AzureSearchTable

我们蔚蓝的搜索索引现在指向这个表,我必须弄清楚如何检索图书与寻呼可能还有整理用户。 问题是,我需要一本独特的书籍选择,但天蓝色的搜索没有明显区别,我不知道一本书可能有多少文档,所以我无法将Top参数设置为10.一本书可能有30或40个文件,这意味着例如前40行可能只是一本书。

我试图使用书籍ID方面哪种作品,并给我每本书的文件编号和计数,但我似乎无法指定排序顺序 - 顺序是不同的到我为查询设置的订单(BookId)。我也不知道如何使用方面获得所有书籍 - 我可以在该方面设置计数属性,但我不知道用户将拥有多少本书。

我们的建筑师说我应该得到所有行(可能是数千),并在C#代码中过滤它们以获得10本书。这对我来说似乎相当低效,但感觉不对。

所以我不知道这是正确的做法..

  • 我应该有图书和文件数据分开蔚蓝的搜索索引(使用单独的表?
  • 我怎么回报不知道每本书有多少个文档?
  • 我可以使用C#sdk指定排序顺序吗?(我认为可以通过其余的API)
  • 我该如何得到一个方面为用户返回所有书籍?

回答

3

这里有几个想法:

子弹#1回答:

如果你的目的是为了能够返回基于搜索DocumentName的图书列表,那么你可能想让他们保持在同一个指数。您的架构师在C#中处理结果的想法可能并不像您想象的那么糟糕。你可以在LINQ中做一个GroupBy。 Azure搜索查询速度很快,LINQ查询也很快。特别是如果发布Azure搜索查询的计算机是Azure Web/App服务器并且位于相同区域(数据中​​心内通信)。即使使用了Advice API,我也可以使用这种方法实现自动完成功能,该功能需要在用户输入时快速返回结果(在几百毫秒内)。我想说,至少值得一试,看看你用最大和典型的数据集获得什么样的表现。

但是,如果这对您不适用,那么请考虑重新构造您的索引架构,以便DocumentName的类型为Collection(Edm.String)。你会是这个样子:

{ 
    id: 20663, 
    userId: 1, 
    bookId: 2144, 
    bookName: "ber", 
    documentName: ["asdasd", "_318-1991.jpg", "wallhaven-13081.png", etc...], 
    documentCount: 7 
} 

现在,如果你需要允许用户得到有关他们选择你可以做与数据库调用来获取书某本书的文件详细信息细节。或者,这也是您为可能为创建另一个具有更详细文档信息的文档的Azure搜索索引。但是,在用户工作流程中的这一点上,除非您要在该特定图书的文档中提供另一个全文搜索,那么您可能只想坚持采用逐个拜访的DB调用方式。

子弹#2回答:

对于文档指望你可以创建另一个字段(如上图所示),并在该排序/过滤/面。

子弹#3的答案:

无论是SDK还是Azure的搜索REST API提供一种方式来订购面本身,但请记住,你最终有您要如何显示方面信息的完全控制在UI中。如果SDK没有提供您需要的内容,您可以在您的应用程序中创建一个简单的查找类,以根据需要订购您的方面。事情是这样的:

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回答:

要返回所有书籍为特定的用户,你可以再补充一个过滤器表达式是这样的:

userId eq <put_authenticated_userid_here> 

这是假设目前经过身份验证的用户应该只能看到他们自己的书籍。但是,如果您希望能够在一个方面有一个用户列表来筛选其中的一个或多个用户,那么需要对索引架构进行另一次重新构造,以使书籍文档上的一个新字段被称为类似“用户”是用户名的集合(Edm.String)。像这样:

{ 
    ... 
    users: ["Luke Skywalker", "Han Solo", "Chewbacca", etc...] 
    ... 
} 
+0

您好@Matthew感谢您的更新。我为每本书的一行创建了一个新的搜索索引和一个新的表格数据表,而且到目前为止,事情似乎仍然正常。我阅读了有关索引的Collection(Edm.String)类型,但它并不直观,至少对我而言并非如此。你认为使用这样的两个搜索索引是否有缺点? –

+0

这取决于您必须搜索/过滤哪些文档的属性。你是否需要能够搜索/过滤DocumentName或文档的其他属性(如文档的内容或类似的内容)? –

+0

是的,我们的文档表中有一堆其他文本字段,例如设备名称,位置地址,城市,街道等。所有这些字段都可以在索引(对于文档)中搜索到。新表(用于书籍)上的新索引将仅用于返回每本书的名称和ID以及每本书具有的文档数。 –