diff --git a/db/migration/20200423204116_add_sort_fields.go b/db/migration/20200423204116_add_sort_fields.go
new file mode 100644
index 000000000..db5e9f2ce
--- /dev/null
+++ b/db/migration/20200423204116_add_sort_fields.go
@@ -0,0 +1,64 @@
+package migration
+
+import (
+	"database/sql"
+	"github.com/pressly/goose"
+)
+
+func init() {
+	goose.AddMigration(Up20200423204116, Down20200423204116)
+}
+
+func Up20200423204116(tx *sql.Tx) error {
+	_, err := tx.Exec(`
+alter table artist
+	add order_artist_name varchar(255) collate nocase;
+alter table artist
+	add sort_artist_name varchar(255) collate nocase;
+create index if not exists artist_order_artist_name
+	on artist (order_artist_name);
+
+alter table album
+	add order_album_name varchar(255) collate nocase;
+alter table album
+	add order_album_artist_name varchar(255) collate nocase;
+alter table album
+	add sort_album_name varchar(255) collate nocase;
+alter table album
+	add sort_artist_name varchar(255) collate nocase;
+alter table album
+	add sort_album_artist_name varchar(255) collate nocase;
+create index if not exists album_order_album_name
+	on album (order_album_name);
+create index if not exists album_order_album_artist_name
+	on album (order_album_artist_name);
+
+alter table media_file
+	add order_album_name varchar(255) collate nocase;
+alter table media_file
+	add order_album_artist_name varchar(255) collate nocase;
+alter table media_file
+	add order_artist_name varchar(255) collate nocase;
+alter table media_file
+	add sort_album_name varchar(255) collate nocase;
+alter table media_file
+	add sort_artist_name varchar(255) collate nocase;
+alter table media_file
+	add sort_album_artist_name varchar(255) collate nocase;
+alter table media_file
+	add sort_title varchar(255) collate nocase;
+create index if not exists media_file_order_album_name
+	on media_file (order_album_name);
+create index if not exists media_file_order_artist_name
+	on media_file (order_artist_name);
+`)
+	if err != nil {
+		return err
+	}
+	notice(tx, "A full rescan will be performed to change the search behaviour")
+	return forceFullRescan(tx)
+}
+
+func Down20200423204116(tx *sql.Tx) error {
+	return nil
+}
diff --git a/model/album.go b/model/album.go
index 69820cc47..3028bf025 100644
--- a/model/album.go
+++ b/model/album.go
@@ -3,23 +3,28 @@ package model
 import "time"
 
 type Album struct {
-	ID            string    `json:"id"            orm:"column(id)"`
-	Name          string    `json:"name"`
-	CoverArtPath  string    `json:"coverArtPath"`
-	CoverArtId    string    `json:"coverArtId"`
-	ArtistID      string    `json:"artistId"      orm:"pk;column(artist_id)"`
-	Artist        string    `json:"artist"`
-	AlbumArtistID string    `json:"albumArtistId" orm:"pk;column(album_artist_id)"`
-	AlbumArtist   string    `json:"albumArtist"`
-	MaxYear       int       `json:"maxYear"`
-	MinYear       int       `json:"minYear"`
-	Compilation   bool      `json:"compilation"`
-	SongCount     int       `json:"songCount"`
-	Duration      float32   `json:"duration"`
-	Genre         string    `json:"genre"`
-	FullText      string    `json:"fullText"`
-	CreatedAt     time.Time `json:"createdAt"`
-	UpdatedAt     time.Time `json:"updatedAt"`
+	ID                   string    `json:"id"            orm:"column(id)"`
+	Name                 string    `json:"name"`
+	CoverArtPath         string    `json:"coverArtPath"`
+	CoverArtId           string    `json:"coverArtId"`
+	ArtistID             string    `json:"artistId"      orm:"pk;column(artist_id)"`
+	Artist               string    `json:"artist"`
+	AlbumArtistID        string    `json:"albumArtistId" orm:"pk;column(album_artist_id)"`
+	AlbumArtist          string    `json:"albumArtist"`
+	MaxYear              int       `json:"maxYear"`
+	MinYear              int       `json:"minYear"`
+	Compilation          bool      `json:"compilation"`
+	SongCount            int       `json:"songCount"`
+	Duration             float32   `json:"duration"`
+	Genre                string    `json:"genre"`
+	FullText             string    `json:"fullText"`
+	SortAlbumName        string    `json:"sortAlbumName"`
+	SortArtistName       string    `json:"sortArtistName"`
+	SortAlbumArtistName  string    `json:"sortAlbumArtistName"`
+	OrderAlbumName       string    `json:"orderAlbumName"`
+	OrderAlbumArtistName string    `json:"orderAlbumArtistName"`
+	CreatedAt            time.Time `json:"createdAt"`
+	UpdatedAt            time.Time `json:"updatedAt"`
 
 	// Annotations
 	PlayCount int       `json:"playCount"   orm:"-"`
diff --git a/model/artist.go b/model/artist.go
index a771e12dc..123e9c19d 100644
--- a/model/artist.go
+++ b/model/artist.go
@@ -3,10 +3,12 @@ package model
 import "time"
 
 type Artist struct {
-	ID         string `json:"id"          orm:"column(id)"`
-	Name       string `json:"name"`
-	AlbumCount int    `json:"albumCount"  orm:"column(album_count)"`
-	FullText   string `json:"fullText"`
+	ID              string `json:"id"          orm:"column(id)"`
+	Name            string `json:"name"`
+	AlbumCount      int    `json:"albumCount"  orm:"column(album_count)"`
+	FullText        string `json:"fullText"`
+	SortArtistName  string `json:"sortArtistName"`
+	OrderArtistName string `json:"orderArtistName"`
 
 	// Annotations
 	PlayCount int       `json:"playCount"   orm:"-"`
diff --git a/model/mediafile.go b/model/mediafile.go
index 14115a49d..bb1772ecc 100644
--- a/model/mediafile.go
+++ b/model/mediafile.go
@@ -6,28 +6,34 @@ import (
 )
 
 type MediaFile struct {
-	ID            string    `json:"id"            orm:"pk;column(id)"`
-	Path          string    `json:"path"`
-	Title         string    `json:"title"`
-	Album         string    `json:"album"`
-	ArtistID      string    `json:"artistId"      orm:"pk;column(artist_id)"`
-	Artist        string    `json:"artist"`
-	AlbumArtistID string    `json:"albumArtistId"`
-	AlbumArtist   string    `json:"albumArtist"`
-	AlbumID       string    `json:"albumId"       orm:"pk;column(album_id)"`
-	HasCoverArt   bool      `json:"hasCoverArt"`
-	TrackNumber   int       `json:"trackNumber"`
-	DiscNumber    int       `json:"discNumber"`
-	Year          int       `json:"year"`
-	Size          int       `json:"size"`
-	Suffix        string    `json:"suffix"`
-	Duration      float32   `json:"duration"`
-	BitRate       int       `json:"bitRate"`
-	Genre         string    `json:"genre"`
-	FullText      string    `json:"fullText"`
-	Compilation   bool      `json:"compilation"`
-	CreatedAt     time.Time `json:"createdAt"`
-	UpdatedAt     time.Time `json:"updatedAt"`
+	ID                   string    `json:"id"            orm:"pk;column(id)"`
+	Path                 string    `json:"path"`
+	Title                string    `json:"title"`
+	Album                string    `json:"album"`
+	ArtistID             string    `json:"artistId"      orm:"pk;column(artist_id)"`
+	Artist               string    `json:"artist"`
+	AlbumArtistID        string    `json:"albumArtistId"`
+	AlbumArtist          string    `json:"albumArtist"`
+	AlbumID              string    `json:"albumId"       orm:"pk;column(album_id)"`
+	HasCoverArt          bool      `json:"hasCoverArt"`
+	TrackNumber          int       `json:"trackNumber"`
+	DiscNumber           int       `json:"discNumber"`
+	Year                 int       `json:"year"`
+	Size                 int       `json:"size"`
+	Suffix               string    `json:"suffix"`
+	Duration             float32   `json:"duration"`
+	BitRate              int       `json:"bitRate"`
+	Genre                string    `json:"genre"`
+	FullText             string    `json:"fullText"`
+	SortTitle            string    `json:"sortTitle"`
+	SortAlbumName        string    `json:"sortAlbumName"`
+	SortArtistName       string    `json:"sortArtistName"`
+	SortAlbumArtistName  string    `json:"sortAlbumArtistName"`
+	OrderAlbumName       string    `json:"orderAlbumName"`
+	OrderAlbumArtistName string    `json:"orderAlbumArtistName"`
+	Compilation          bool      `json:"compilation"`
+	CreatedAt            time.Time `json:"createdAt"`
+	UpdatedAt            time.Time `json:"updatedAt"`
 
 	// Annotations
 	PlayCount int       `json:"playCount"   orm:"-"`
diff --git a/persistence/album_repository.go b/persistence/album_repository.go
index 0d62843d8..c0cadc5e8 100644
--- a/persistence/album_repository.go
+++ b/persistence/album_repository.go
@@ -115,6 +115,8 @@ func (r *albumRepository) Refresh(ids ...string) error {
 	}
 	var albums []refreshAlbum
 	sel := Select(`album_id as id, album as name, f.artist, f.album_artist, f.artist_id, f.album_artist_id, 
+		f.sort_album_name, f.sort_artist_name, f.sort_album_artist_name,
+		f.order_album_name, f.order_album_artist_name,
 		f.compilation, f.genre, max(f.year) as max_year, sum(f.duration) as duration, 
 		count(*) as song_count, a.id as current_id, f.id as cover_art_id, f.path as cover_art_path, f.has_cover_art, 
 		group_concat(f.artist, ' ') as song_artists, group_concat(f.year, ' ') as years`).
@@ -148,7 +150,8 @@ func (r *albumRepository) Refresh(ids ...string) error {
 			toInsert++
 			al.CreatedAt = time.Now()
 		}
-		al.FullText = getFullText(al.Name, al.Artist, al.AlbumArtist, al.SongArtists)
+		al.FullText = getFullText(al.Name, al.Artist, al.AlbumArtist, al.SongArtists,
+			al.SortAlbumName, al.SortArtistName, al.SortAlbumArtistName)
 		_, err := r.put(al.ID, al.Album)
 		if err != nil {
 			return err
diff --git a/persistence/artist_repository.go b/persistence/artist_repository.go
index 7b161b241..12f0aa281 100644
--- a/persistence/artist_repository.go
+++ b/persistence/artist_repository.go
@@ -56,7 +56,7 @@ func (r *artistRepository) getIndexKey(a *model.Artist) string {
 }
 
 func (r *artistRepository) Put(a *model.Artist) error {
-	a.FullText = getFullText(a.Name)
+	a.FullText = getFullText(a.Name, a.SortArtistName)
 	_, err := r.put(a.ID, a)
 	return err
 }
@@ -111,7 +111,9 @@ func (r *artistRepository) Refresh(ids ...string) error {
 		CurrentId string
 	}
 	var artists []refreshArtist
-	sel := Select("f.album_artist_id as id", "f.album_artist as name", "count(*) as album_count", "a.id as current_id").
+	sel := Select("f.album_artist_id as id", "f.album_artist as name", "count(*) as album_count", "a.id as current_id",
+		"f.sort_album_artist_name as sort_artist_name",
+		"f.order_album_artist_name as order_artist_name").
 		From("album f").
 		LeftJoin("artist a on f.album_artist_id = a.id").
 		Where(Eq{"f.album_artist_id": ids}).
diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go
index a725e2f68..3c893b9f3 100644
--- a/persistence/mediafile_repository.go
+++ b/persistence/mediafile_repository.go
@@ -41,7 +41,8 @@ func (r mediaFileRepository) Exists(id string) (bool, error) {
 }
 
 func (r mediaFileRepository) Put(m *model.MediaFile) error {
-	m.FullText = getFullText(m.Title, m.Album, m.Artist, m.AlbumArtist)
+	m.FullText = getFullText(m.Title, m.Album, m.Artist, m.AlbumArtist,
+		m.SortTitle, m.SortAlbumName, m.SortArtistName, m.SortAlbumArtistName)
 	_, err := r.put(m.ID, m)
 	return err
 }
diff --git a/scanner/metadata_ffmpeg.go b/scanner/metadata_ffmpeg.go
index 9ca90a6d4..cf154507c 100644
--- a/scanner/metadata_ffmpeg.go
+++ b/scanner/metadata_ffmpeg.go
@@ -3,6 +3,7 @@ package scanner
 import (
 	"bufio"
 	"errors"
+	"fmt"
 	"mime"
 	"os"
 	"os/exec"
@@ -27,7 +28,11 @@ type Metadata struct {
 func (m *Metadata) Title() string               { return m.getTag("title", "sort_name") }
 func (m *Metadata) Album() string               { return m.getTag("album", "sort_album") }
 func (m *Metadata) Artist() string              { return m.getTag("artist", "sort_artist") }
-func (m *Metadata) AlbumArtist() string         { return m.getTag("album_artist") }
+func (m *Metadata) AlbumArtist() string         { return m.getTag("album_artist", "albumartist") }
+func (m *Metadata) SortTitle() string           { return m.getSortTag("title", "name") }
+func (m *Metadata) SortAlbum() string           { return m.getSortTag("album") }
+func (m *Metadata) SortArtist() string          { return m.getSortTag("artist") }
+func (m *Metadata) SortAlbumArtist() string     { return m.getSortTag("albumartist", "album_artist") }
 func (m *Metadata) Composer() string            { return m.getTag("composer", "tcm", "sort_composer") }
 func (m *Metadata) Genre() string               { return m.getTag("genre") }
 func (m *Metadata) Year() int                   { return m.parseYear("date") }
@@ -99,7 +104,7 @@ var (
 	inputRegex = regexp.MustCompile(`(?m)^Input #\d+,.*,\sfrom\s'(.*)'`)
 
 	//    TITLE           : Back In Black
-	tagsRx = regexp.MustCompile(`(?i)^\s{4,6}(\w+)\s*:(.*)`)
+	tagsRx = regexp.MustCompile(`(?i)^\s{4,6}([\w-]+)\s*:(.*)`)
 
 	//  Duration: 00:04:16.00, start: 0.000000, bitrate: 995 kb/s`
 	durationRx = regexp.MustCompile(`^\s\sDuration: ([\d.:]+).*bitrate: (\d+)`)
@@ -230,6 +235,18 @@ func (m *Metadata) getTag(tags ...string) string {
 	return ""
 }
 
+func (m *Metadata) getSortTag(tags ...string) string {
+	formats := []string{"sort%s", "sort_%s", "sort-%s", "%ssort", "%s_sort", "%s-sort"}
+	var all []string
+	for _, tag := range tags {
+		for _, format := range formats {
+			name := fmt.Sprintf(format, tag)
+			all = append(all, name)
+		}
+	}
+	return m.getTag(all...)
+}
+
 func (m *Metadata) parseTuple(tags ...string) (int, int) {
 	for _, tagName := range tags {
 		if v, ok := m.tags[tagName]; ok {
diff --git a/scanner/metadata_test.go b/scanner/metadata_test.go
index 649fc02a4..cd7b2e73f 100644
--- a/scanner/metadata_test.go
+++ b/scanner/metadata_test.go
@@ -204,6 +204,30 @@ Tracklist:
 			md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithMultilineComment)
 			Expect(md.Comment()).To(Equal(expectedComment))
 		})
+
+		It("parses sort tags correctly", func() {
+			const output = `
+Input #0, mp3, from '/Users/deluan/Downloads/椎名林檎 - 加爾基 精液 栗ノ花 - 2003/02 - ドツペルゲンガー.mp3':
+  Metadata:
+    title-sort      : Dopperugengā
+    album           : 加爾基 精液 栗ノ花
+    artist          : 椎名林檎
+    album_artist    : 椎名林檎
+    title           : ドツペルゲンガー
+    albumsort       : Kalk Samen Kuri No Hana
+    artist_sort     : Shiina, Ringo
+    ALBUMARTISTSORT : Shiina, Ringo
+`
+			md, _ := extractMetadata("tests/fixtures/test.mp3", output)
+			Expect(md.Title()).To(Equal("ドツペルゲンガー"))
+			Expect(md.Album()).To(Equal("加爾基 精液 栗ノ花"))
+			Expect(md.Artist()).To(Equal("椎名林檎"))
+			Expect(md.AlbumArtist()).To(Equal("椎名林檎"))
+			Expect(md.SortTitle()).To(Equal("Dopperugengā"))
+			Expect(md.SortAlbum()).To(Equal("Kalk Samen Kuri No Hana"))
+			Expect(md.SortArtist()).To(Equal("Shiina, Ringo"))
+			Expect(md.SortAlbumArtist()).To(Equal("Shiina, Ringo"))
+		})
 	})
 
 	Context("parseYear", func() {
diff --git a/scanner/tag_scanner.go b/scanner/tag_scanner.go
index db3f5ee43..6402cc902 100644
--- a/scanner/tag_scanner.go
+++ b/scanner/tag_scanner.go
@@ -262,6 +262,10 @@ func (s *TagScanner) toMediaFile(md *Metadata) model.MediaFile {
 	mf.Suffix = md.Suffix()
 	mf.Size = md.Size()
 	mf.HasCoverArt = md.HasPicture()
+	mf.SortTitle = md.SortTitle()
+	mf.SortAlbumName = md.SortAlbum()
+	mf.SortArtistName = md.SortArtist()
+	mf.SortAlbumArtistName = md.SortAlbumArtist()
 
 	// TODO Get Creation time. https://github.com/djherbis/times ?
 	mf.CreatedAt = md.ModificationTime()