Как индексировать многомерные массивы в CouchDB

У меня есть многомерный массив, который я хочу проиндексировать с помощью CouchDB (на самом деле с помощью Cloudant). У меня есть пользователи, у которых есть список команд, к которым они принадлежат. Я хочу искать, чтобы найти каждого члена этой команды. Итак, дайте мне все объекты User, у которых есть командный объект с идентификатором 79d25d41d991890350af672e0b76faed. Я попытался создать json-индекс для «Teams.id», но это не сработало, потому что это не прямой массив, а многомерный массив.

Пользователь

{
 "_id": "683be6c086381d3edc8905dc9e948da8",
 "_rev": "238-963e54ab838935f82f54e834f501dd99",
 "type": "Feature",
 "Kind": "Profile",
 "Email": "[email protected]",
 "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"
}

person Blane Townsend    schedule 03.03.2016    source источник


Ответы (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

person brobes    schedule 04.03.2016

Вам просто нужно пройтись по массиву Teams и создать запись представления для каждой из команд.

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 к запросу.

person Kerr    schedule 04.03.2016