Как включить разные каталоги в запрос в MongoDB? - PullRequest
0 голосов
/ 30 декабря 2011

Предположим, у меня есть разные документы в разных коллекциях:

На автомобилях :

{ "_id": 32534534, "color": "red", ... }

На домах :

{ "_id": 93867, "city": "Xanadu", ... }

Как я могу получить соответствующий документ для документов ниже, в чел. :

{ "name": "Alonso", "owns": [32534534], ... }
{ "name": "Kublai Khan", "owns": [93867], ... }

Могу ли я использовать что-то вроде кода ниже? (Обратите внимание, что я не указываю каталог)

db.find({'_id': 93867})

Если нет, что бы вы предложили для достижения этого эффекта?


Я только что нашел этот связанный вопрос: MongoDB: запросы кросс-коллекции

Ответы [ 3 ]

2 голосов
/ 04 января 2012

Используя DBrefs , вы можете хранить ссылки на документы вне вашей коллекции или даже в другой базе данных mongodb.Вам придется извлекать ссылки в отдельных запросах, разные драйверы обрабатывают это по-разному, например, с помощью драйвера python вы можете автоопределение .

Ваш пример в оболочке js может выглядетьнапример:

> red_car = {"color": "red", "model": "Ford Perfect"}
{"color": "red", "model": "Ford Perfect"}
> db.cars.save(red_car)
> red_car
{
    "color" : "red",
    "model" : "Ford Perfect",
    "_id" : ObjectId("4f041d96874e6f24e704f887")
}
> // Save as DBRef
> alonso = {"name": "Alonso", "owns": [new DBRef('cars', red_car._id)]}
{
    "name" : "Alonso",
    "owns" : [
        {
            "$ref" : "cars",
            "$id" : ObjectId("4f041d96874e6f24e704f887")
        }
    ]
}
> db.people.save(alonso)

Как видите, DBRef - это формальная спецификация для ссылок на объекты, которая всегда содержит ObjectId, но также может содержать информацию о базе данных и коллекции.В приведенном выше примере вы можете увидеть, как коллекция cars хранится в поле $ref.Поиск тривиален, так как вы просто делаете запрос к dbref:

> dbref = new DBRef('cars', red_car._id)
> red_car_owner = db.people.find({"owns": {$in: [dbref]}})[0]
> red_car_owner
{
    "_id" : ObjectId("4f0448e3a1c5cd097fc36a65"),
    "name" : "Alonso",
    "owns" : [
        {
            "$ref" : "cars",
            "$id" : ObjectId("4f0448d1a1c5cd097fc36a64")
        }
    ]
}

Разыменование можно выполнить с помощью команды fetch() в оболочке:

> red_car_owner.owns[0].fetch()
{
    "_id" : ObjectId("4f0448d1a1c5cd097fc36a64"),
    "color" : "red",
    "model" : "Ford Perfect"
}

Однако, в зависимости от вашего использованияна случай, если вы захотите оптимизировать это и написать некоторый код, который перебирает массив owns и выполняет как можно меньше запросов find() ...

0 голосов
/ 30 декабря 2011

Вам необходимо изменить структуру документа о людях, чтобы добавить тип

{ "name": "Alonso", "owns": {ids:[32534534],type:'car'} ... }
{ "name": "Kublai Khan", "owns":{ids:[93867],type:'house'} ... }

, чтобы теперь вы могли найти людей, владеющих автомобилем красного цвета, на

db.people.find({type:car,ids:32534534})

идома по

db.people.find({type:house,ids:93867})
0 голосов
/ 30 декабря 2011

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

{ "_id": 32534534, "type": "car", "color": "red", ... }
{ "_id": 93867, "type": "house", "city": "Xanadu", ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...