Вот расширение, которое могло бы помочь. Это пересечет все узлы в Вашей иерархии объектов и выберет тех, которые соответствуют критериям. Это предполагает, что каждый объект в Вашей иерархии имеет свойство набора, которое содержит его дочерние объекты.
/// Traverses an object hierarchy and return a flattened list of elements
/// based on a predicate.
///
/// TSource: The type of object in your collection.</typeparam>
/// source: The collection of your topmost TSource objects.</param>
/// selectorFunction: A predicate for choosing the objects you want.
/// getChildrenFunction: A function that fetches the child collection from an object.
/// returns: A flattened list of objects which meet the criteria in selectorFunction.
public static IEnumerable<TSource> Map<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> selectorFunction,
Func<TSource, IEnumerable<TSource>> getChildrenFunction)
{
// Add what we have to the stack
var flattenedList = source.Where(selectorFunction);
// Go through the input enumerable looking for children,
// and add those if we have them
foreach (TSource element in source)
{
flattenedList = flattenedList.Concat(
getChildrenFunction(element).Map(selectorFunction,
getChildrenFunction)
);
}
return flattenedList;
}
Первый нам нужны объект и иерархия вложенного объекта.
А простой класс
class Node
{
public int NodeId { get; set; }
public int LevelId { get; set; }
public IEnumerable<Node> Children { get; set; }
public override string ToString()
{
return String.Format("Node {0}, Level {1}", this.NodeId, this.LevelId);
}
}
узла И метод для получения 3-уровневой глубокой иерархии узлов
private IEnumerable<Node> GetNodes()
{
// Create a 3-level deep hierarchy of nodes
Node[] nodes = new Node[]
{
new Node
{
NodeId = 1,
LevelId = 1,
Children = new Node[]
{
new Node { NodeId = 2, LevelId = 2, Children = new Node[] {} },
new Node
{
NodeId = 3,
LevelId = 2,
Children = new Node[]
{
new Node { NodeId = 4, LevelId = 3, Children = new Node[] {} },
new Node { NodeId = 5, LevelId = 3, Children = new Node[] {} }
}
}
}
},
new Node { NodeId = 6, LevelId = 1, Children = new Node[] {} }
};
return nodes;
}
Первый Тест: сгладьте иерархию, никакая фильтрация
[Test]
public void Flatten_Nested_Heirachy()
{
IEnumerable<Node> nodes = GetNodes();
var flattenedNodes = nodes.Map(
p => true,
(Node n) => { return n.Children; }
);
foreach (Node flatNode in flattenedNodes)
{
Console.WriteLine(flatNode.ToString());
}
// Make sure we only end up with 6 nodes
Assert.AreEqual(6, flattenedNodes.Count());
}
, Это покажет:
Node 1, Level 1
Node 6, Level 1
Node 2, Level 2
Node 3, Level 2
Node 4, Level 3
Node 5, Level 3
1115-секундный Тест: Получите список узлов, которые имеют четный NodeId
[Test]
public void Only_Return_Nodes_With_Even_Numbered_Node_IDs()
{
IEnumerable<Node> nodes = GetNodes();
var flattenedNodes = nodes.Map(
p => (p.NodeId % 2) == 0,
(Node n) => { return n.Children; }
);
foreach (Node flatNode in flattenedNodes)
{
Console.WriteLine(flatNode.ToString());
}
// Make sure we only end up with 3 nodes
Assert.AreEqual(3, flattenedNodes.Count());
}
, который Это покажет:
Node 6, Level 1
Node 2, Level 2
Node 4, Level 3
Во-первых, обратите внимание, что CouchDB не является реляционной базой данных SQL, как MySQL. Я не уверен, может ли описанный вами запрос быть выражен в CouchDB (но я не эксперт по этому поводу).
При этом, вот несколько ссылок:
Я нашел ссылку на эту статью в другом SO-вопросе о производительности MySQL и CouchDB, но я не знаю, имеет ли это значение.
Один из способов, которым couchdb может способствовать значительному увеличению скорости, - это его репликация. Он может реплицироваться через соединения с высокой задержкой, возможно, даже до клиентского сайта, если инфраструктура безопасности поддерживает это. Таким образом, у вас может быть несколько баз данных в нескольких физических местах, не убивая себя.
Когда я провел несколько сравнений самостоятельно, я обнаружил, что скорость couch примерно вдвое меньше, чем у oracle для сценария с большим количеством вставок 100 тыс. Вставок пока читатели читали. Это, конечно, не сильная сторона дивана, так как читателям приходилось перестраивать просмотры, пока происходили вставки.
Я бы порекомендовал вам настроить тест самостоятельно. Почему ? CouchDb и MySql - очень разные звери, и то, как вы решите организовать данные в каждом из них, будет очень зависеть от вашей проблемной области. Следовательно, то, как вы их запрашиваете, также будет отличаться.
Я думаю, что некоторые фиктивные данные в каждом из них и некоторые тесты сами по себе будут более полезными, чем просмотр результатов какого-либо произвольного теста. Я понимаю, что это займет некоторое время само по себе, но я думаю, что это лучший путь вперед.
Именно так. Основное отличие состоит в том, что: реляционный vs нереляционный. И это зависит от того, что вам нужно. Есть движение по этому поводу: http://en.wikipedia.org/wiki/NoSQL
И еще один хороший нереляционный БД:
www.mongodb.org
Одна из лучших аналогий, которые я слышал, - это то, что CouchDB не хочет быть Ferrari, он хочет быть Honda, то есть не самой быстрой, но самой надежной.