Вы правы в определенном утверждении документа BSON, это не XML-документ. Поскольку XML загружается в древовидную структуру, состоящую из «узлов», поиск на арбитальном ключе довольно прост.
Документ MonoDB не так прост в обработке, и это «база данных» во многих так что обычно ожидается, что он будет иметь определенную «однородность» местоположений данных, чтобы упростить «индексирование» и поиск.
Тем не менее это можно сделать. Но, конечно, это означает, что на сервере выполняется рекурсивный процесс, и это означает, что обработка JavaScript с помощью $where
.
В качестве примера базовой оболочки, но общий function
просто строковый аргумент для оператора $where
всюду:
db.collection.find(
function () {
var findKey = "find-this",
findVal = "please find me";
function inspectObj(doc) {
return Object.keys(doc).some(function(key) {
if ( typeof(doc[key]) == "object" ) {
return inspectObj(doc[key]);
} else {
return ( key == findKey && doc[key] == findVal );
}
});
}
return inspectObj(this);
}
)
Итак, в основном, проверьте ключи, присутствующие в объекте, чтобы увидеть, соответствуют ли они желаемому «имени поля» и содержимому. Если какой-либо из этих ключей является «объектом», то запишите его в функцию и проверьте снова.
JavaScript .some()
гарантирует, что найденное совпадение будет найдено из функции поиска, дающей результат true
и возвращающий объект, где этот «ключ / значение» присутствовал на некоторой глубине.
Обратите внимание, что $where
по существу означает перемещение всей вашей коллекции, если только не существует какой-либо другой действительный фильтр запросов, который может быть применен к «индексу» в коллекции.
Так что используйте с осторожностью или вообще не работайте и просто работайте с реструктуризацией данных в более работоспособную форму.
Но это даст вам ваш матч.
Сошлитесь на Систему. Сеть dll в Вашей модели и Системе использования. Сеть. Кэширование. Кэш
public string[] GetNames()
{
string[] names = Cache["names"] as string[];
if(names == null) //not in cache
{
names = DB.GetNames();
Cache["names"] = names;
}
return names;
}
Немного упрощенный, но я предполагаю, что это работало бы. Это не MVC конкретный, и я всегда использовал этот метод для кэширования данных.
Можно также попытаться использовать кэширование, встроенное в ASP MVC:
Добавляют следующий атрибут к методу контроллера, который требуется кэшировать:
[OutputCache(Duration=10)]
В этом случае ActionResult этого будет кэшироваться в течение 10 секунд.
[еще 115] на этом здесь
Вот хороший и простой класс/сервис помощника кэша, который я использую:
using System.Runtime.Caching;
public class InMemoryCache: ICacheService
{
public T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class
{
T item = MemoryCache.Default.Get(cacheKey) as T;
if (item == null)
{
item = getItemCallback();
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(10));
}
return item;
}
}
interface ICacheService
{
T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class;
}
cacheProvider.GetOrSet("cache key", (delegate method if cache is empty));
поставщик Кэша проверит, существует ли что-нибудь под названием "идентификатор кэша" в кэше, и если нет, это назовет метод делегата выбрать данные и сохранить его в кэше.
var products=cacheService.GetOrSet("catalog.products", ()=>productRepository.GetAll())
Я имею в виду сообщение TT и предлагаю следующий подход:
Ссылка на DLL System.Web в своей модели и использование System.Web.Caching.Cache
public string[] GetNames()
{
var noms = Cache["names"];
if(noms == null)
{
noms = DB.GetNames();
Cache["names"] = noms;
}
return ((string[])noms);
}
Вы не должны вернуть значение, повторно прочитанное из кеша, так как вы никогда не узнаете, находится ли оно в кеше в этот конкретный момент. Даже если вы вставляли его в оператор раньше, он мог уже исчезнуть или никогда не был добавлен в кеш - вы просто не знаете.
Таким образом, вы добавляете данные, прочитанные из базы данных, и возвращаете их напрямую, а не повторно -чтение из кеша.