具有contains的CosmosDB Linq查询不是IDocumentQuery类型

时间:2019-06-03 12:41:24

标签: c# linq azure-cosmosdb

我有一个正在使用CosmosDB的项目。最初,我将预览用于EFCore,但实际上还不够成熟,因此我决定选择使用Cosmonaut。我有一个linq语句,该语句基本上看两个属性是否包含子字符串列表-基本上我正在尝试执行以下操作:

SELECT * FROM c WHERE CONTAINS(c.Name, ListOfNames) AND CONTAINS(c.Producer, ListOfProducers);

或者一大堆:

foreach(var name in nameList) {
    foreach(var producer in producerList){

        SELECT * FROM c WHERE c.Name == searchedName AND c.Producer == searchedProducer;
    }
}

这与带有以下Linq查询的EFCore SQL适配器一起使用:

public async void Search(List<string> producers, List<string> names){

 await _store.Entity.Where(x => producers.Any(p => x.Producer.Contains(p)) && names.Any(w => x.Name.Contains(w))).ToListAsync()
}

但是,这与cosmonaut库(从cosmos中封装了DocumentDB客户端)一起提供了以下异常:

Input is not of type IDocumentQuery

看看specs for Contains,我可以这样做:

USE AdventureWorks2012;  
GO  
SELECT Name  
FROM Production.Product  
WHERE CONTAINS(Name, '"chain*" OR "full*"');  
GO

但是在CosmosDB数据浏览器中执行以下操作会得到0个结果:

SELECT * FROM c WHERE CONTAINS(c.Name, '"Test" OR "Test2"')

常规包含以下内容:

SELECT * FROM c WHERE CONTAINS(c.Name, "Test")

也许我的策略是错误的。我想要结合使用它的主要原因是为了获得更好的性能。我的搜索域是大约100.000个文档,其中有多达1000个生产者+名称的列表。因此,基本上我想看看是否可以在文档列表中找到给定的生产者+名称组合。

最好的问候

1 个答案:

答案 0 :(得分:1)

首先,您不应该混合使用T-SQL和Cosmos SQL API。 Cosmos db具有类似sql的查询语法,但不支持T-SQL(适用于MS SQL)。

第二,Cosmos SQL API中的CONTAINS是字符串运算符,因此您不能将其用于数组。

我认为您正在寻找IN keyword

所以实际上您需要下一个查询:

SELECT * FROM c WHERE (c.Name IN("Test", "Test2")) AND (c.Producer IN("Producer1", "Producer2"))

我还没有使用过宇航员库,但是在Microsoft LINQ提供程序的Document DB中,您的查询应如下所示:

var data = yourQueryable.Where(x => producers.Contains(x.Producer) && names.Contains(x.Name)).ToList();