2017-02-17 7 views
0

У меня есть MongoDB документы с довольно сложной структурой:Область поиска в MongoDB, хочет подэлемент, а не весь документ

Top уровень организации (один элемент)

десятки атрибутов, в том числе интересно основателей и менеджеры

основатели - список учредителей, каждый из которых имеет фамилию, имя, отчество (и другие атрибуты)

То же самое с менеджеров - список элементов с ФАМИЛИЯ, имя, отчество (и другие атрибуты)

Я хочу искать в одном запросе на LastName + FirstName + отчества комбо. Запрос должен поддерживать несколько lastnames, firstnames, отчества (с помощью $ в) (это для разных названий одного человека, т.е. джон, джон, Johny)

Мой текущий код возвращает организации с Lastname + FirstName + отчества комбо внутри ORGANIZATION, но мне нужно имя + имя + патроним комбо внутри PERSON. Является ли это возможным? Был бы благодарен даже за правильное направление, а не за код. Насколько я понимаю, $ elemMatch не поможет мне, или это будет очень громоздкий запрос? Возможно, существуют более чистые варианты?

Я уже пытался изменить

List<BasicDBObject> args 

для

BasicDBObject name 

и заполнить его добавления. Ничего не изменилось.

Мой код:

List<BasicDBObject> args = new ArrayList<>(); 
args.add(new BasicDBObject("founders.typeperson.person.lastname", new BasicDBObject("$in", request.getLastnames()))); 
args.add(new BasicDBObject("founders.typeperson.person.firstname", new BasicDBObject("$in", request.getFirstnames()))); 
args.add(new BasicDBObject("founders.typeperson.person.patronym", new BasicDBObject("$in", request.getPatronyms()))); 
argsListUL.add(new BasicDBObject("$and", args)); 

result = collection.find(new BasicDBObject("$or", argsListUL)).into(new ArrayList<Document>()); 

На самом деле, есть гораздо больше DBObjects в окончательном argsListUL, но я удалил этот код для простоты.

update Попытка построить простой запрос в оболочке с помощью $ elemMatch. Странно, но это не работает:

db.collection.find({ "founders.typeperson.person": { $elemMatch: { "lastname": "bla" , "firstname": "bla","patronym" : "bla" } } }).pretty() 

получает 0 результатов. Хотя в БД существует комбинация последнего имени + имя + патроним.

Другое примечание: база данных составляет 500 ГБ, поэтому я думаю, что $ elemMatch в проецировании будет слишком медленным.

ответ

0

Возможно, вам стоит попробовать поделиться своей схемой базы данных. Ваша схема базы данных неясна из вашего вопроса.

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

{ 
    "_id": ObjectId(''), 
    "organization": "x", 
    founders: [ 
    { 
     lastname: 'a' 
     firstname: 'a', 
     patronym: 'a' 
    }, 
    { 
     lastname: 'b' 
     firstname: 'b', 
     patronym: 'b' 
    } 
    ], 
    managers: [ 
    { 
     { 
     lastname: 'c' 
     firstname: 'c', 
     patronym: 'c' 
     }, 
     { 
     lastname: 'd' 
     firstname: 'd', 
     patronym: 'd' 
     } 
    } 
    ] 

} 

Я могу предложить вам изучить конвейер агрегации.

Запрос, который вы можете использовать, чтобы получить только вложенные документы будут: -

db.collection.aggregate([{ 
    $match: { 
    'organization': '<name>' 
    } 
}, { 
    $unwind: '$managers' 
}, { 
    $unwind: '$founders' 
}, { 
    $match: { 

    $or: [{ 
     $or: [{ 
     "managers.lastname": { 
      $regex: 'searchString', 
      $options: 'i' 
     } 
     }, { 
     "managers.firstname": { 
      $regex: 'searchString', 
      $options: 'i' 
     } 
     }, { 
     "managers.patronym": { 
      $regex: 'searchString', 
      $options: 'i' 
     } 
     }] 
    }, { 
     $or: [{ 
     "founders.lastname": { 
      $regex: 'searchString', 
      $options: 'i' 
     } 
     }, { 
     "founders.firstname": { 
      $regex: 'searchString', 
      $options: 'i' 
     } 
     }, { 
     "founders.patronym": { 
      $regex: 'searchString', 
      $options: 'i' 
     } 
     }] 
    }] 
    } 
}, { 
    $group: { 
    "_id": { 
     "_id": "$_id", 
     "organization": "$organization", 
    }, 
    "founders": { 
     "$push": '$founders' 
    }, 
    "managers": { 
     "$push": '$managers' 
    } 
    } 
}, { 
    $project: { 
    "_id": 0, 
    "founders": 1, 
    "managers" 1 
    } 
}]) 

Если данные будут храниться в основоположниках & менеджеры поддокумент не большой, запрос $ регулярного выражения не приведет к какому-либо узким местом.

+0

Благодарим за ответ. Вы, как правило, правы в отношении структуры, но мой поиск не по имени организации, а по комбинации полного имени. И набор данных довольно большой, 500 ГБ: 60 млн. Организаций (каждый из которых имеет от 1 до 10000 учредителей). Сейчас я думаю - самым быстрым способом будет объединение полного имени в поле ONE. Таким образом, он будет работать быстро. –

+0

Хорошо, так что вы хотите, чтобы искать основателей и менеджеров этих 60 миллионов организаций одновременно. Вы оштрафовали свою базу данных? –

 Смежные вопросы

  • Нет связанных вопросов^_^