优化 Azure 认知搜索中的条件查询
Optimise conditional queries in Azure cognitive search
我们在使用 Azure 搜索其中一个项目时遇到了一个独特的场景。因此,我们的客户希望尊重用户的隐私,因此我们提供了一项功能,用户可以限制搜索任何 PII 数据。因此,如果用户选择了隐私,我们只能使用用户 ID 搜索 him/her,否则我们可以使用名称、Phone、城市、用户 ID 等搜索
JSON 选择隐私的地方:
{
"Id": "<Any GUID>",
"Name": "John Smith", //searchable
"Phone": "9987887856", //searchable
"OtherInfo": "some info" //non-searchable
"Address" : {}, //searchable
"Privacy" : "yes", //searchable
"UserId": "XXX1234", //searchable
...
}
JSON 未选择隐私的地方:
{
"Id": "<Any GUID>",
"Name": "Tom Smith", //searchable
"Phone": "7997887856", //searchable
"OtherInfo": "some info" //non-searchable
"Address" : {}, //searchable
"Privacy" : "no", //searchable
"UserId": "XXX1234", //searchable
...
}
现在我们提供搜索服务,将任何 searchText 作为输入并获取与其匹配的所有数据(所有可搜索字段)。
在上述情况下,
- 如果 searchText 与 UserId[=40 不匹配,我们需要删除那些“隐私”为“是”的结果=]
- 如果 searchText 与 UserId 匹配,我们会将其包含在结果中。
- 如果“隐私”设置为“否”并且 searchText 匹配任何可搜索字段,它将包含在结果中。
因此我们使用“Lucene Analysers”在查询时对其进行检查,导致查询非常长,如下所示。让我们假设 searchText = "abc"
((Name: abc OR Phone: abc OR UserId: abc ...) AND Privacy: no) OR
((UserId: abc ) AND Privacy: yes)
这是在我们显示分页结果时完成的,即按 1 - 10、11 - 20 等分批处理数据,因此,我们在每个查询中获得前 10 条记录以及总结果数。
还有其他优化方法吗??
或者 Azure 搜索服务促进了条件查询的任何内部机制?
从客户端,您可以动态添加“SearchFields”参数作为查询的一部分,这样,如果用户将隐私标志设置为 true,则只有 UserId 被设置为可用搜索字段的一部分。
https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.search.models.searchparameters.searchfields?view=azure-dotnet
如果我对你的需求理解正确,可以很容易地解决。您确定哪些 属性 应该是可搜索的,而不是在您的数据模型中。您不需要构造复杂的查询来为每个 属性 重复最终用户输入。而且您不需要对结果进行任何批处理或处理。
如果 searchText 是您的用户输入,您可以使用:
(*searchText* AND Privacy:false)
这将搜索所有可搜索字段,但它只会搜索允许在 PII 数据中搜索的 return 条记录。
您还有一个要求,即允许用户在所有记录中搜索 userid,而不管记录的 PII 设置如何。为了支持这一点,将查询扩展到:
(*searchText* AND Privacy:false) OR (UserId:*searchText*)
这允许用户搜索 Privacy 为 false 的记录中的所有字段,对于所有其他记录,它只允许在 UserId 中搜索。此查询模式将通过一个优化查询解决您的所有需求。
我们在使用 Azure 搜索其中一个项目时遇到了一个独特的场景。因此,我们的客户希望尊重用户的隐私,因此我们提供了一项功能,用户可以限制搜索任何 PII 数据。因此,如果用户选择了隐私,我们只能使用用户 ID 搜索 him/her,否则我们可以使用名称、Phone、城市、用户 ID 等搜索
JSON 选择隐私的地方:
{
"Id": "<Any GUID>",
"Name": "John Smith", //searchable
"Phone": "9987887856", //searchable
"OtherInfo": "some info" //non-searchable
"Address" : {}, //searchable
"Privacy" : "yes", //searchable
"UserId": "XXX1234", //searchable
...
}
JSON 未选择隐私的地方:
{
"Id": "<Any GUID>",
"Name": "Tom Smith", //searchable
"Phone": "7997887856", //searchable
"OtherInfo": "some info" //non-searchable
"Address" : {}, //searchable
"Privacy" : "no", //searchable
"UserId": "XXX1234", //searchable
...
}
现在我们提供搜索服务,将任何 searchText 作为输入并获取与其匹配的所有数据(所有可搜索字段)。 在上述情况下,
- 如果 searchText 与 UserId[=40 不匹配,我们需要删除那些“隐私”为“是”的结果=]
- 如果 searchText 与 UserId 匹配,我们会将其包含在结果中。
- 如果“隐私”设置为“否”并且 searchText 匹配任何可搜索字段,它将包含在结果中。
因此我们使用“Lucene Analysers”在查询时对其进行检查,导致查询非常长,如下所示。让我们假设 searchText = "abc"
((Name: abc OR Phone: abc OR UserId: abc ...) AND Privacy: no) OR
((UserId: abc ) AND Privacy: yes)
这是在我们显示分页结果时完成的,即按 1 - 10、11 - 20 等分批处理数据,因此,我们在每个查询中获得前 10 条记录以及总结果数。
还有其他优化方法吗?? 或者 Azure 搜索服务促进了条件查询的任何内部机制?
从客户端,您可以动态添加“SearchFields”参数作为查询的一部分,这样,如果用户将隐私标志设置为 true,则只有 UserId 被设置为可用搜索字段的一部分。 https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.search.models.searchparameters.searchfields?view=azure-dotnet
如果我对你的需求理解正确,可以很容易地解决。您确定哪些 属性 应该是可搜索的,而不是在您的数据模型中。您不需要构造复杂的查询来为每个 属性 重复最终用户输入。而且您不需要对结果进行任何批处理或处理。
如果 searchText 是您的用户输入,您可以使用:
(*searchText* AND Privacy:false)
这将搜索所有可搜索字段,但它只会搜索允许在 PII 数据中搜索的 return 条记录。
您还有一个要求,即允许用户在所有记录中搜索 userid,而不管记录的 PII 设置如何。为了支持这一点,将查询扩展到:
(*searchText* AND Privacy:false) OR (UserId:*searchText*)
这允许用户搜索 Privacy 为 false 的记录中的所有字段,对于所有其他记录,它只允许在 UserId 中搜索。此查询模式将通过一个优化查询解决您的所有需求。