DocumentDB 按数组过滤数组
DocumentDB filter an array by an array
我有一个文档,基本上是这样的:
{
"Name": "John Smith",
"Value": "SomethingIneed",
"Tags: ["Tag1" ,"Tag2", "Tag3"]
}
我的目标是编写一个查询,在其中查找数据库中 Tag
属性 包含过滤器中所有标签的所有文档。
例如,在上面的例子中,我的查询可能是 ["Tag1", "Tag3"]
。我想要所有其标签集合包含 Tag1 和 Tag3 的文档。
我做了以下事情:
尝试了 All Contains 类型的 linq 查询
var tags = new List<string>() {"Test", "TestAccount"};
var req =
Client.CreateDocumentQuery<Contact>(UriFactory.CreateDocumentCollectionUri("db", "collection"))
.Where(x => x.Tags.All(y => tags.Contains(y)))
.ToList();
创建了一个用户定义的函数(我根本无法让它工作)
var tagString = "'Test', 'TestAccount'";
var req =
Client.CreateDocumentQuery<Contact>(UriFactory.CreateDocumentCollectionUri("db", "collection"),
$"Select c.Name, c.Email, c.id from c WHERE udf.containsAll([${tagString}] , c.Tags)").ToList();
containsAll 定义为:
function arrayContainsAnotherArray(needle, haystack){
for(var i = 0; i < needle.length; i++){
if(haystack.indexOf(needle[i]) === -1)
return false;
}
return true;
}
使用 System.Linq.Dynamic 从字符串创建谓词
var query = new StringBuilder("ItemType = \"MyType\"");
if (search.CollectionValues.Any())
{
foreach (var searchCollectionValue in search.CollectionValues)
{
query.Append($" and Collection.Contains(\"{searchCollectionValue}\")");
}
}
3 实际上对我有用,但查询非常昂贵(在 10K 文档的集合上超过 2000 RU)并且我疯狂地受到限制。我的应用程序第一次迭代的结果集必须能够在结果集中支持 10K 个结果。如何使用过滤器数组查询大量结果?
谢谢。
UDF 可以工作,但它将是一个完整的 table 扫描,因此不推荐,除非结合其他高度选择性的标准。
我认为最高效(使用索引)的方法是将其拆分为一系列 AND
语句。您可以通过编程方式构建查询字符串来执行此操作(出于安全原因,请小心完全转义和用户提供的数据)。因此,生成的查询如下所示:
SELECT *
FROM c
WHERE
ARRAY_CONTAINS(c.Tags, "Tag1") AND
ARRAY_CONTAINS(c.Tags, "Tag3")
我有一个文档,基本上是这样的:
{
"Name": "John Smith",
"Value": "SomethingIneed",
"Tags: ["Tag1" ,"Tag2", "Tag3"]
}
我的目标是编写一个查询,在其中查找数据库中 Tag
属性 包含过滤器中所有标签的所有文档。
例如,在上面的例子中,我的查询可能是 ["Tag1", "Tag3"]
。我想要所有其标签集合包含 Tag1 和 Tag3 的文档。
我做了以下事情:
尝试了 All Contains 类型的 linq 查询
var tags = new List<string>() {"Test", "TestAccount"}; var req = Client.CreateDocumentQuery<Contact>(UriFactory.CreateDocumentCollectionUri("db", "collection")) .Where(x => x.Tags.All(y => tags.Contains(y))) .ToList();
创建了一个用户定义的函数(我根本无法让它工作)
var tagString = "'Test', 'TestAccount'";
var req = Client.CreateDocumentQuery<Contact>(UriFactory.CreateDocumentCollectionUri("db", "collection"), $"Select c.Name, c.Email, c.id from c WHERE udf.containsAll([${tagString}] , c.Tags)").ToList();
containsAll 定义为:
function arrayContainsAnotherArray(needle, haystack){
for(var i = 0; i < needle.length; i++){
if(haystack.indexOf(needle[i]) === -1)
return false;
}
return true;
}
使用 System.Linq.Dynamic 从字符串创建谓词
var query = new StringBuilder("ItemType = \"MyType\""); if (search.CollectionValues.Any()) { foreach (var searchCollectionValue in search.CollectionValues) { query.Append($" and Collection.Contains(\"{searchCollectionValue}\")"); } }
3 实际上对我有用,但查询非常昂贵(在 10K 文档的集合上超过 2000 RU)并且我疯狂地受到限制。我的应用程序第一次迭代的结果集必须能够在结果集中支持 10K 个结果。如何使用过滤器数组查询大量结果?
谢谢。
UDF 可以工作,但它将是一个完整的 table 扫描,因此不推荐,除非结合其他高度选择性的标准。
我认为最高效(使用索引)的方法是将其拆分为一系列 AND
语句。您可以通过编程方式构建查询字符串来执行此操作(出于安全原因,请小心完全转义和用户提供的数据)。因此,生成的查询如下所示:
SELECT *
FROM c
WHERE
ARRAY_CONTAINS(c.Tags, "Tag1") AND
ARRAY_CONTAINS(c.Tags, "Tag3")