У меня есть база данных MongoDB, содержащая 500000 документа в одной коллекции, используемой сервисом ASP Net Core для фильтрации документов, в основном выполняющих много операций CRUD. Установка представляет собой автономную базу данных MongoDB. Мои документы содержат много полей, но один отфильтрован в каждом запросе, который является полем token . Я создал много составных индексов с этим полем и всеми остальными полем, которые я использую для сортировки. Из примера я создал следующий индекс: < /p>
{ v: 2, key: { token: 1, updateDate: -1 }, name: 'TokenUpdateDate' }
, которые фильтровали документы на основе поля токена и других возможных полей и сортируют их на основе поля обновления. В MongoDB Compass я вижу, что все мои запросы используют мои индексы, которые хороши и ускоряют мои запросы. Однако при фильтрации поля токена с использованием $ в операторе, иногда он может в конечном итоге составлять до 30-40 значений в нем, и когда это происходит, производительность запроса резко падает, хотя используется индекс. Это не может быть изменено, поэтому я хочу спросить, есть ли какое -либо решение или, может быть, другой подход для этого конкретного варианта использования. Есть ли другой способ отфильтровать использование $ в операторе или лучший индекс? Я использую последнюю версию драйвера MongoDB C#.return await _propertiesCollection
.Aggregate()
.Match(addedFilter)
.Sort(sortDefinition)
.Project(x => new PropertyListItem
{
Id = x.Id,
CustomCode = x.CustomCode,
CategoryId = x.CategoryId,
SubCategoryId = x.SubCategoryId,
AimId = x.AimId,
AreaId = x.AreaId,
AreaGr = x.AreaGr,
AreaEn = x.AreaEn,
SubAreaId = x.SubAreaId,
SubAreaGr = x.SubAreaGr,
SubAreaEn = x.SubAreaEn,
Price = x.Price,
SqrMeters = x.SqrMeters,
PricePerSqrm = x.PricePerSqrm,
Rooms = x.Rooms,
Bathrooms = x.Bathrooms,
Wc = x.Wc,
Levels = x.Levels,
YoutubeVideo = x.YoutubeVideo,
VirtualTour = x.VirtualTour,
TotalParkings = x.TotalParkings,
Mandates = x.Mandates,
Images = x.Images
.OrderBy(u => u.OrderNum),
Auctions = x.Auctions,
Flags = x.Flags,
Project = x.Project,
ProjectProperties = x.ProjectProperties,
AuctionPercentage = x.Characteristics
.Where(u => u.Id == 412)
.Select(u => u.Value)
.FirstOrDefault(),
AuctionInfo = x.Characteristics
.Where(u => u.Id == 401)
.Select(u => u.Value)
.FirstOrDefault(),
AuctionOwnership = x.Characteristics
.Where(u => u.Id == 406)
.Select(u => u.Value)
.FirstOrDefault(),
Characteristics = filterProjects != null && filterProjects.Value == true
? x.Characteristics.Where(u => u.Id == 302)
: Array.Empty()
})
.Skip(pageSize * page - pageSize)
.Limit(pageSize)
.ToListAsync(cancellationToken: cancellationToken);
addfilter был бы фильтрованием фильтров и создает фильтры, подобные этим:
var filter = _filterBuilderProperties
.Eq(item => item.Id, property.Id);
filter &= _filterBuilderProperties
.Eq(item => item.Token, token);
< /code>
Один запросы, генерируемые в монгошоле: < /p>
aggregate([
{
"$match": {
"$and": [
{ "categoryId" : 1 }, { "token" : { "$in" : ["59fc092f-b54d-42bc-9c95-134220ab79d7"] } }] } }, { "$sort" : { "updateDate" : -1 } }, { "$project" : { "_id" : "$id", "CustomCode" : "$customCode", "CategoryId" : "$categoryId", "SubCategoryId" : "$subCategoryId", "AimId" : "$aimId", "AreaId" : "$areaId", "AreaGr" : "$areaGr", "AreaEn" : "$areaEn", "SubAreaId" : "$subAreaId", "SubAreaGr" :"$subAreaGr",
"SubAreaEn": "$subAreaEn",
"Price": "$price",
"SqrMeters": "$sqrMeters",
"PricePerSqrm": "$pricePerSqrm",
"Rooms": "$rooms",
"Bathrooms": "$bathrooms",
"Wc": "$wc",
"Levels" : "$levels",
"YoutubeVideo" : "$youtubeVideo",
"VirtualTour" : "$virtualTour",
"TotalParkings" : "$totalParkings",
"Mandates" : "$mandates",
"Images" : { "$sortArray" : { "input" : "$images", "sortBy" : { "orderNum" : 1 } } }, "Auctions" : "$auctions", "Flags" : "$flags", "Project" : "$project", "ProjectProperties" : "$projectProperties", "AuctionPercentage" : { "$let": {
"vars": {
"values": {
"$map": {
"input": {
"$filter": {
"input": "$characteristics",
"as": "u",
"cond": {
"$eq": [
"$$u._id",
412
]
}
}
},
"as": "u",
"in": "$$u.value"
}
}
},
"in": {
"$cond": {
"if": {
"$eq": [
{
"$size": "$$values"
},
0
]
},
"then": null,
"else": {
"$arrayElemAt": [
"$$values",
0
]
}
}
}
}
},
"AuctionInfo": {
"$let": {
"vars": {
"values": {
"$map": {
"input": {
"$filter": {
"input": "$characteristics",
"as": "u",
"cond": {
"$eq": [
"$$u._id",
401
]
}
}
},
"as": "u",
"in": "$$u.value"
}
}
},
"in": {
"$cond": { "if" : { "$eq" : [{ "$size" : "$$values" }, 0] }, "then" : null, "else" : { "$arrayElemAt" : ["$$values", 0] } } } } }, "AuctionOwnership" : { "$let" : { "vars" : { "values" : { "$map" : { "input" : { "$filter" : { "input" : "$characteristics", "as" : "u", "cond" : { "$eq" : ["$$u._id", 406] } } }, "as" : "u", "in" : "$$u.value" } } }, "in" : { "$cond" : { "if" : { "$eq" : [{ "$size" : "$$values" }, 0] }, "then" : null, "else" : { "$arrayElemAt" : ["$$values", 0] } } } } }, "Characteristics" : [] } }, { "$skip" : 0 }, { "$limit" : 18 }])
< /code>
и поле токена может закончиться: < /p>
token: {$in: ["04490892-dc1d-4ddf-9d9f-3322036d496a","8761e684-0c63-443c-8f91-2f6f70ae3eaa","2b333c40-12ef-4aa0-8acb-52be7af18948","6927ddbc-7d0a-4208-a22b-82ea2989e8f3","28a29a92-f26e-47e5-ba92-364c8fac814f","dbb4be57-af9b-4ee4-be1d-d7b29bfffd9d","f3d98dbf-d518-43ca-9562-dd595b3170e6","fe027387-72de-41e4-8110-71c2a5bc39ac","66c04f3b-79ac-4982-b404-3170347ab68d","facd245c-69b1-412d-8565-a94747b4098c","ec972bee-5a23-496c-9739-8b8842130bd5","0c1a8953-5cf2-4d6c-ab34-9e00aa144b07","ccf34324-6543-435b-91a2-5c24d5cd9013","3f91c659-7659-493d-ab8a-7eb92ea88088","1ce7d820-7b1a-4d75-ba05-8a595deb6bf8","b3e3d07d-6256-4ca3-b2c3-b39852e24e0f","f38b5251-a916-445c-a257-1426a899bd17","6d44bb06-9212-4252-9c63-08b90a13619d","7f330f3c-c004-45ae-9c14-9d0b4928af6a","f40c145d-0a83-4df8-9e1b-9b93cbb9e79f","5ee5e73e-4f24-40c1-8a9f-0334044dfe6b","0b30dd64-6e04-4128-9688-c0dd44d995be"]}
Подробнее здесь: https://stackoverflow.com/questions/794 ... in-mongodb