[英]C# MongoDB Driver - How to filter by arrays and a list of items
我想對字符串數組執行搜索並將其與字符串列表中的任何字符串進行比較。 例如:
這是數據結構:
{
"CategoryIds": [ "A123", "B456", "C789" ]
}
這是搜索詞:
List<string> search = new List<string> { "A123", "C789" };
我正在動態構建我的搜索查詢,所以我為開始定義了這些:
var builder = Builders<Item>.Filter;
ar filters = Builders<Item>.Filter.Empty;
我已經嘗試了以下所有方法,但都沒有奏效:
使用ElemMatch
filters &= builder.ElemMatch(i => i.CategoryIds, id => search.CategoryIds.Any(i => i.Equals(id)));
使用Intersect
filters &= builder.Where(i => search.CategoryIds.Intersect(i.CategoryIds).Any());
唯一有效的是這個:
var categoryFilters = new List<FilterDefinition<Item>>();
foreach (string id in search.CategoryIds)
categoryFilters.Add(builder.AnyEq(i => i.CategoryIds, id));
if (categoryFilters.Any())
filters &= builder.Or(categoryFilters);
但這似乎有點矯枉過正。 有更簡單的方法嗎?
對於上面的確切用例如果我們想應用限制或跳過,當然我們可以在 linq 中做,但這將從集合中取出滿足過濾條件的整個文檔,然后將在其上應用限制或跳過條件,因此,對於更大的數據集,建議在數據庫級別本身應用這些東西。
一個更好的方法是為此建立一個聚合管道,如果有人正在尋找它,下面是代碼
一個小的變化,我們可以用一個包含搜索元素的 BsonArray 代替列表。
// Your search Array
BsonArray search = new BsonArray
{
"A123", "C789"
};
//Pipeline
var pipeline1 = new BsonDocument(
new BsonDocument
("$match",
new BsonDocument
( "CategoryIds",
new BsonDocument
("$elemMatch",
new BsonDocument
("$in",
search
)
)
)
)
);
BsonDocument[] pipeline = new BsonDocument[] { pipeline1 };
var results = await collection.Aggregate<BsonDocument>(pipeline).ToListAsync();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.