2016-04-13 5 views
3

В настоящее время я использую Dexie.js для хранения данных локально. У меня есть 3 разных таблицы, которые соединены друг с другом с помощью внешних ключей. Мне удалось настроить схему и вставить соответствующие данные. Однако, когда я хочу получить данные, мне не удалось найти пример того, как присоединиться к различным таблицам.Dexie.js - как присоединиться к столам?

Вот пример:

var db = new Dexie('my-testing-db'); 
db.delete().then(function() { 

    db.version(1).stores({ 
    genres: '++id,name', 
    albums: '++id,name,year,*tracks', 
    bands: '++id,name,*albumsId,genreId' 
    }); 

    db.transaction('rw', db.genres, db.albums, db.bands, function() { 
    var rock = db.genres.add({ 
     name: 'rock' 
     }), 
     jazz = db.genres.add({ 
     name: 'jazz' 
     }); 

    var justLookAround = db.albums.add({ 
     name: 'Just Look Around', 
     year: 1992, 
     tracks: [ 
     'We want the truth', 'Locomotive', 'Shut me out' 
     ] 
    }); 

    var sickOfItAll = db.bands.add({ 
     name: 'Sick Of it All' 
    }); 

    justLookAround.then(function(album_id) { 
     rock.then(function(rock_id) { 
     sickOfItAll.then(function(band_id) { 
      db.bands.update(band_id, { 
      genreId: rock_id, 
      albumsId: [album_id] 
      }).then(function(updated) { 

      }); 
     }); 
     }); 
    }); 

    }).then(function() { 
    //how to join the tables here???? 
    db.bands.each(function(band) { 
     console.log(band); 
    }); 
    }); 
}); 

ответ

4

Вот как присоединиться к результату. Disclaimber: код не проверен!

var all = Dexie.Promise.all; 

function joinBands (bandCollection) { 

    // Start by getting all bands as an array of band objects 
    return bandCollection.toArray(function(bands) { 

     // Query related properties: 
     var genresPromises = bands.map(function (band) { 
      return db.genres.get(band.genreId || 0); 
     }); 
     var albumsPromises = bands.map(function (band) { 
      return db.albums.where('id').anyOf(band.albumsId || []).toArray(); 
     }); 

     // Await genres and albums queries: 
     return all ([ 
      all(genresPromises), 
      all(albumsPromises)¨ 
     ]).then(function (genresAndAlbums) { 

      // Now we have all foreign keys resolved and 
      // we can put the results onto the bands array 
      // before returning it: 
      bands.forEach(function (band, i) { 
       band.genre = genresAndAlbums[0][i]; 
       band.albums = genresAndAlbums[1][i]; 
      }); 
      return bands; 
     }); 
    }); 
} 

// Join all: 
joinBands(db.bands.toCollection()).then(function (bands) { 
    alert ("All bands: " + JSON.stringify(bands, null, 4)); 
}).catch(function (error) { 
    alert ("Oops: " + error); 
}); 

// Query and join: 
joinBands(db.bands.where('genreId').anyOf([1,5,19]).limit(25)).then(function (bands) { 
    alert ("Some bands: " + JSON.stringify(bands, null, 4)); 
}).catch (function (error) { 
    alert ("Oops: " + error); 
}); 

Предпочтительно называть joinBands() внутри транзакции для ускорения запросов вверх, а также получить более надежный и атомный результат.

+0

Я хотел бы это было * немного * более интуитивным ;-) – cmroanirgo

1

К сожалению, я приехал сюда из Google ищет фактического соединения, вы знаете, что-то в этом роде:

db.bands.where(...).equals(..).join(
    db.genres.where(...).etc(), 'genreId -> genres.id').then(
    function(band, genre) { ... }); 

Это, я думаю, что ближе к тому, что спросил оригинал спрашивающий, но основанный на ответ, предоставленный @ david-fahlander, кажется, что этот плагин, https://github.com/ignasbernotas/dexie-relationships, может быть немного проще, если вы хотите построить красивое дерево объектов.

ридми плагина очень похож на ваш пример, поэтому я скопировал его дословно здесь:

Схема

Обратите внимание на использование ->, который устанавливает внешние ключи.

import Dexie from 'dexie' 
import relationships from 'dexie-relationships' 

var db = new Dexie('MusicBands', {addons: [relationships]}) 

db.version(1).stores({ 
    genres: 'id, name', 
    bands: 'id, name, genreId -> genres.id', 
    albums: 'id, name, bandId -> bands.id, year' 
}); 

Использование

db.bands 
    .where('name').startsWithAnyOf('A', 'B') // can be replaced with your custom query 
    .with({albums: 'albums', genre: 'genreId'}) // makes referred items included 
    .then(bands => { 
     // Let's print the result: 
     bands.forEach (band => { 
      console.log (`Band Name: ${band.name}`) 
      console.log (`Genre: ${band.genre.name}`) 
      console.log (`Albums: ${JSON.stringify(band.albums, null, 4)}`) 
     }); 
}) 
Смежные вопросы