DocumentDB 按数组过滤数组

DocumentDB filter an array by an array

我有一个文档,基本上是这样的:

{
     "Name": "John Smith",
     "Value": "SomethingIneed",
     "Tags: ["Tag1" ,"Tag2", "Tag3"]
 }

我的目标是编写一个查询,在其中查找数据库中 Tag 属性 包含过滤器中所有标签的所有文档。

例如,在上面的例子中,我的查询可能是 ["Tag1", "Tag3"]。我想要所有其标签集合包含 Tag1 和 Tag3 的文档。

我做了以下事情:

  1. 尝试了 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();
    
  2. 创建了一个用户定义的函数(我根本无法让它工作)

    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;
 }
  1. 使用 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")