Как индексировать многомерные массивы в 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 на запрос.

Другие вопросы по тегам