Получить документы, имеющие массив, содержащий другой атрибут документа

Я храню какую-то файловую систему в Mongo, где каталоги называются категориями.

Категория JSON выглядит так:

{
   "name":"CategoryChildLevel2",
   "parentId":"2",
   "otherAttribute":"anyVal",
   "breadcrumb":[
      {
         "name":"RootCategory",
         "id":"1"
      },
      {
         "name":"CategoryChildLevel1",
         "id":"2"
      }
   ]
}

Категории FS связаны друг с другом атрибутом parentId.

Мне нужно отобразить хлебные крошки категорий. Благодаря пользовательской навигации мы можем знать, где мы находимся в FS, но доступ к категориям можно получить непосредственно по их идентификатору (категория с закладками, поисковая система...), без какой-либо навигации FS. Чтобы избежать рекурсивных обращений к БД, чтобы иметь возможность получить хлебные крошки, я ее денормализовал.


Проблема в том, что эту навигационную цепочку сложно поддерживать в актуальном состоянии, потому что категорию верхнего уровня можно перемещать, и, следовательно, все ее дочерние навигационные крошки должны обновляться. Может быть много дочерних категорий для обновления, и есть разные способы решения этой проблемы. Некоторые из них безопасны, но дороги (рекурсия), а другие быстрее, но могут привести к некоторым несоответствиям.


Здесь я хотел бы знать, возможно ли выполнить запрос для извлечения категорий, которые имеют плохую навигационную крошку. Мне нужен запрос, который позволяет сделать:

Получить все категории, которые не имеют: последний элемент массива хлебная крошка.id = parentId

Я не думаю, что часть «последний элемент массива» возможна, но было бы неплохо иметь возможность сделать:

Получить все категории, которые не имеют: Breadcrumb.id содержит parentId

Любое решение, доступное в драйвере Scala или Java? Я использую Salat/Casbah.

Этот вопрос может помочь вам понять, с чем я столкнулся: их">Какую БД вы бы использовали? MongoDB/Neo4j/SQL... все?


person Sebastien Lorber    schedule 28.12.2012    source источник
comment
никто не знает решения?   -  person Sebastien Lorber    schedule 02.01.2013
comment
Как делать деревья всегда зависит от ваших запросов. Как вам нужно искать это дерево? Являются ли категории в настоящее время отдельными от списков файлов для FS, так что у вас есть одна коллекция categories, а затем одна из files? К сожалению, в большинстве баз данных деревья — непростая вещь, и обычно требуется рекурсия либо при поиске, либо при обновлении, причем наиболее производительным является тот, который подходит для ваших наиболее часто используемых запросов.   -  person Sammaye    schedule 02.01.2013
comment
Если у вас есть время читать, ответ есть в ссылке, которую я даю в конце :) Есть 2 отдельные коллекции для категорий и файлов. Но файлы должны знать о своей цепочке, чтобы при печати результатов поиска (например, 20 результатов на странице) навигационная цепочка была доступна из коробки без необходимости 20 дорогостоящих рекурсий.   -  person Sebastien Lorber    schedule 02.01.2013
comment
Хм, ссылка немного короткая, если честно. Думали ли вы о документах здесь: docs.mongodb.org/manual/tutorial /model-tree-structures особенно материализованные пути. Это тяжелое обновление, но его легче запрашивать. Ваша хлебная крошка немного избыточна, потому что у вас есть проблема, заключающаяся в том, что вы передали имя категории всем ее дочерним элементам, создавая подмножество объектов. Если бы вместо этого вы использовали пути, вы могли бы удовлетворить довольно много ваших запросов, например find({path: /,06060607/}) для определения того, находится ли этот идентификатор в конце.   -  person Sammaye    schedule 02.01.2013
comment
Может быть, вы также можете определить эти 20 запросов? Я вижу по одному запросу на дочернюю категорию, содержащую родительский банкомат.   -  person Sammaye    schedule 02.01.2013


Ответы (1)


Вы можете выполнить запрос Retrieve all the categories that do not have: last array element breadcrumb.id = parentId с помощью $where. оператор:

db.test.find({
    // Find docs were breadcrumb is empty or its last element's id != parentId
    $where: '!this.breadcrumb.length || this.breadcrumb[this.breadcrumb.length-1].id !== this.parentId' 
})
person JohnnyHK    schedule 03.01.2013