当使用Any()或Contains()时,mongo-Db不支持的过滤器类型-有任何解决方法/修复吗



我看到过这类问题的其他线索,但突出显示的答案都不适合我。

引发错误的代码就是这个

List<Distribution> distributionPublishQueueList = (mongoDb.GetCollection<Distribution>().Find(Builders<Distribution>.Filter.And(
Builders<Distribution>.Filter.Where(x => x.Status == EntityStatus.Ok),
Builders<Distribution>.Filter.Where(x => x.IsActive),
Builders<Distribution>.Filter.Where(x => distinctDistributionIdInPublishQueueList.Contains(x.Id))))).ToList();

最初的代码是这样的:

List<Distribution> distributionPublishQueueList = 
(await mongoDb.GetCollection<Distribution>()
.FindAsync(x => x.Status == EntityStatus.Ok 
&& x.IsActive
&& distinctDistributionIdInPublishQueueList.Contains(x.Id)))
.ToList();

但我试着让它对蒙哥人更友好。上面的两段代码是相同的。列表distinctDistributionIdInPublishQueueList是作为字符串的分发Id的列表。因此,我试图找到Id在该列表中的所有分发版+其他2个过滤器。当我在过滤器定义中使用contains时,它会抛出一个不支持的过滤器异常。但以下代码之所以有效,是因为我将列表放入本地内存,并使用LINQ对其进行处理:

List<Distribution> distributionPublishQueueList = (await mongoDb.GetCollection<Distribution>().FindAsync(x => x.Status == EntityStatus.Ok && x.IsActive)).ToList();
distributionPublishQueueList = distributionPublishQueueList.Where(x => distinctDistributionIdInPublishQueueList.Contains(x.Id)).ToList();

由于数据库中存在大量分布,我需要能够在本地内存中不执行此操作。是否有使用Contains和Any的变通方法。我还尝试过使用MongoCSharpDriver-In语句和Builders。滤器In和其他变体。

一个错误示例如下。这是所使用的代码。

List<Asset> assetList = (await mongoDb.GetCollection<Asset>().FindAsync(
asset => extractAssetsFromContentService.ExtractAssetFromDraftContent(contentAsMarkdown)
.Any(extractedAsset => extractedAsset.AssetId == asset.Id))).ToList();

系统。ArgumentException:不支持的筛选器:Any(value(System.Collections.Generic.List`1[DocWorks.Common.Transformation.Model.ExtractedAssetModel](。Where(({document}{AssetId}=={document}{_id}((。

这将是相同的错误,除了当使用Contains而不是Any时,Any将为"Contains"。与分发类似,我无法将资产带入本地内存。所有实体共享相同的基类,该基类按如下方式存储Id:

[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }

您可以使用以下任何解决方案;

var filter = Builders<Distribution>.Filter.ElemMatch(x => x.Distincts, i => distinctIdList.Contains(i.Id));
var results = await (await _collection.FindAsync(filter)).ToListAsync();

Expression<Func<Distribution, bool>> filter = x => districtIdList.Contains(x.Id);
var results = await (await _collection.FindAsync(filter)).ToListAsync();

这两种解决方案在我的项目中效果很好。我有一个图书馆,你可以在那里应用这些用法。当您将expression发送到此处的任何get方法时,它都会起作用。例如

var distributionPublishQueueList = await _distributionRepository.GetAllAsync(x => distinctDistributionIdInPublishQueueList.Contains(x.Id));

您可以在此处查看文档。

最新更新