2016-06-09 2 views
2

Привет У меня есть таблица с форматом, показанным ниже.Получите верхнюю часть от отдельного атрибута на CoreData

Я хочу построить историю, поэтому мне нужны последние сообщения от разных пользователей, упорядоченных по метке времени!

+---+-------------------+-------------------+---------------+ | | Username | Message | Timestamp | +---+-------------------+-------------------+---------------+ | 1 | John | Hello | 486380161.723 | | 2 | Mark | Spreadsheet | 486380264.723 | | 3 | John | FYI | 486380366.723 | | 4 | John | Bye | 486557497.271 | | 5 | Mark | How are you? | 486557597.274 | | 6 | Mario | What? | 486558597.274 | +---+-------------------+-------------------+---------------+

Это то, что мой результат должен быть.

+---+-------------------+-------------------+---------------+ | | Username | Message | Timestamp | +---+-------------------+-------------------+---------------+ | 6 | Mario | What? | 486558597.274 | | 5 | Mark | How are you? | 486557597.274 | | 4 | John | Bye | 486557497.271 | +---+-------------------+-------------------+---------------+

На данный момент, я получаю все отчетливое username, переборе каждый из них и запрашивая сообщения для этого пользователя, упорядоченные по временной метки с limit(1).

Я не доволен этим решением, чтобы кто-нибудь мог помочь мне лучше?

Спасибо, Mário

+0

CoreData не является реляционной базой данных. Это система сохранения объектов. Возможно, вы должны хранить свои сообщения в SQLite? – Paulw11

ответ

3

Это можно сделать в двух выборках, с одной оговоркой, что я буду упоминать, когда я к нему.

Первая выборка получает имена пользователей и самую последнюю метку времени для каждого:

let maxTimestampRequest = NSFetchRequest(entityName: "Entity") 
    maxTimestampRequest.resultType = .DictionaryResultType 

    let maxTimestampExpression = NSExpression(format: "max:(timestamp)") 
    let maxTimestampExpressiondescription = NSExpressionDescription() 
    maxTimestampExpressiondescription.name = "maxTimestamp" 
    maxTimestampExpressiondescription.expression = maxTimestampExpression 
    maxTimestampExpressiondescription.expressionResultType = .DoubleAttributeType 

    maxTimestampRequest.propertiesToFetch = ["username", maxTimestampExpressiondescription] 
    maxTimestampRequest.propertiesToGroupBy = ["username"] 

Execute, что принести, и вы получите массив словарей. Каждый словарь содержит имя пользователя и самую последнюю метку времени для этого пользователя:

Optional([{ 
    maxTimestamp = "486557497.271"; 
    username = John; 
}, { 
    maxTimestamp = "486558597.274"; 
    username = Mario; 
}, { 
    maxTimestamp = "486557597.274"; 
    username = Mark; 
}]) 

Получение полных записей требует второй выборки. Если результаты предыдущих выборок в массиве с именем results,

var predicates = [NSPredicate]() 
    for maxTimestampInfo in results! { 
     let username = maxTimestampInfo["username"]! 
     let timestamp = maxTimestampInfo["maxTimestamp"]! 
     let partialPredicate = NSPredicate(format: "username=%@ and timestamp=%@", argumentArray:[ username, timestamp ]) 
     predicates.append(partialPredicate) 
    } 
    let completePredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates) 

    let fetch = NSFetchRequest(entityName: "Entity") 
    fetch.predicate = completePredicate 

Execute что закачает и вы получите полные управляемые объекты, которые соответствуют вашим требованиям.

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

+0

Спасибо @ Тома. Решение работает отлично. Я отредактирую ваш ответ позже с версией Objc в порядке? –