Как индексировать многомерные массивы в couchdb
У меня есть многомерный массив, который я хочу индексировать с помощью CouchDB (действительно с использованием Cloudant). У меня есть пользователи, у которых есть список команд, к которым они принадлежат. Я хочу искать, чтобы найти каждого члена этой команды. Итак, достань мне все объекты User, которые имеют командный объект с идентификатором 79d25d41d991890350af672e0b76faed. Я пытался создать индекс json для "Teams.id", но это не сработало, потому что это не прямой массив, а многомерный массив.
пользователь
{
"_id": "683be6c086381d3edc8905dc9e948da8",
"_rev": "238-963e54ab838935f82f54e834f501dd99",
"type": "Feature",
"Kind": "Profile",
"Email": "gc@gmail.com",
"FirstName": "George",
"LastName": "Castanza",
"Teams": [
{
"id": "79d25d41d991890350af672e0b76faed",
"name": "First Team",
"level": "123"
},
{
"id": "e500c1bf691b9cfc99f05634da80b6d1",
"name": "Second Team Name",
"level": ""
},
{
"id": "4645e8a4958421f7d843d9b34c4cd9fe",
"name": "Third Team Name",
"level": "123"
}
],
"LastTeam": "79d25d41d991890350af672e0b76faed"
}
2 ответа
Это очень похоже на мой ответ на Cloudant Selector Query, но вот предложение, примененное к вашему вопросу:
Самый простой способ выполнить этот запрос - использовать "Cloudant Query" (или "Mango", как он будет называться в предстоящем выпуске CouchDB 2.0), а не традиционную систему индексации представлений MapReduce в CouchDB. (Этот блог охватывает различия: https://cloudant.com/blog/mango-json-vs-text-indexes/ а этот обзор представляет собой: https://developer.ibm.com/clouddataservices/2015/11/24/cloudant-query-json-index-arrays/).
Вот как должен выглядеть ваш индекс CQ:
{
"index": {
"fields": [
{"name": "Teams.[].id", "type": "string"}
]
},
"type": "text"
}
И как выглядит следующий запрос:
{
"selector": {
"Teams": {"$elemMatch": {"id": "79d25d41d991890350af672e0b76faed"}}
},
"fields": [
"_id",
"FirstName",
"LastName"
]
}
Вы можете попробовать это самостоятельно в разделе "Запрос" на панели управления Cloudant или с помощью curl, например:
curl -H "Content-Type: application/json" -X POST -d '{"selector":{"Teams":{"$elemMatch":{"id":"79d25d41d991890350af672e0b76faed"}}},"fields":["_id","FirstName","LastName"]}' https://broberg.cloudant.com/teams_test/_find
Эта база данных доступна для чтения всем, поэтому вы можете посмотреть образцы документов, которые я там создал, здесь: https://broberg.cloudant.com/teams_test/_all_docs?include_docs=true
Копай тему о Сайнфельде: D
Вам просто нужно перебрать массив команд и создать запись для каждой из команд.
function (doc) {
if(doc.Kind === "Profile"){
for (var i=0; i<doc.Teams.length; i++) {
var team = doc.Teams[i];
emit(team.id, [doc.FirstName, doc.LastName]);
}
}
}
Затем вы можете запросить все профили с определенным идентификатором группы, введя идентификатор группы следующим образом
.../view?key="79d25d41d991890350af672e0b76faed"
дающий
{"total_rows":7,"offset":2,"rows":[
{"id":"0d15041f43b43ae07e8faa737f00032c","key":"79d25d41d991890350af672e0b76faed","value":["Adam","Alpha"]},
{"id":"68779729be3610fd8b52b22574000ae8","key":"79d25d41d991890350af672e0b76faed","value":["Bob","Bravo"]},
{"id":"9f97f1565f03aebae9ca73e207001ee1","key":"79d25d41d991890350af672e0b76faed","value":["Chuck","Charlie"]}
]}
или вы можете включить фактические профили в результат, добавив &include_docs=true
на запрос.