用于领域中搜索的复杂排序,多个RealmResults的并集 [英] Complex sorting for search in realm, union of multiple RealmResults
问题描述
我在开源Linux命令库项目中用领域替换了sqlite.到目前为止一切都很好,但是现在我遇到了问题.
I replaced sqlite with realm in my open source Linux Command Library project. Everything went fine so far, but now I'm facing a problem.
我正在使用RealmBaseAdapter在带有搜索界面的ListView中显示所有命令.对于搜索,下面截断的领域对结果进行排序,如下所示:
I'm using a RealmBaseAdapter to display all the commands in a ListView with an search interface. For a search the realm sniped below orders the results like this:
查询: 测试
结果:
- l2 测试
- rc 测试
- 测试
-
测试 parm
- l2test
- rctest
- test
testparm
RealmResults<Command> commands = mRealm.where(Command.class).contains("name", query).findAll();
mAdapter.updateRealmResults(commands);
使用旧的sqlite逻辑,顺序是这样的:
With the old sqlite logic the order was like this:
结果:
- 测试
- 测试测试
- l2 测试
- rc 测试
- test
- testparm
- l2test
- rctest
return getReadableDatabase().rawQuery("Select * from " + CommandsDBTableModel.TABLE_COMMANDS + " WHERE " + CommandsDBTableModel.COL_NAME + " LIKE '%" + query + "%' " + "ORDER BY " + CommandsDBTableModel.COL_NAME + " = '" + query + "' DESC," + CommandsDBTableModel.COL_NAME + " LIKE '" + query + "%' DESC", null);
是否也可以通过领域来实现? 这是项目链接 https://github.com/SimonSchubert/LinuxCommandBibliotheca
Is it possible to realize it with realm too? Here is the link to the project https://github.com/SimonSchubert/LinuxCommandBibliotheca
推荐答案
谢谢你们,你们俩都帮助我解决了很多问题. @Mateusz Herych @EpicPandaForce
Thank you guys, you both helped me alot to solve the problem. @Mateusz Herych @EpicPandaForce
这是自定义适配器:
public abstract class RealmMultiAdapter<T extends RealmObject> extends BaseAdapter {
private final RealmChangeListener<T> realmChangeListener = new RealmChangeListener<T>() {
@Override
public void onChange(RealmResults<T> t) {
notifyDataSetChanged();
}
};
protected LayoutInflater inflater;
protected List<RealmResults<T>> realmResults;
protected Context context;
public RealmMultiAdapter(Context context, List<RealmResults<T>> realmResults, boolean automaticUpdate) {
if (context == null) {
throw new IllegalArgumentException("Context cannot be null");
}
this.context = context;
this.realmResults = realmResults;
this.inflater = LayoutInflater.from(context);
for(RealmResults<T> results : realmResults) {
results.addChangeListener(realmChangeListener);
}
}
/**
* Returns how many items are in the data set.
*
* @return count of items.
*/
@Override
public int getCount() {
if (realmResults == null) {
return 0;
}
int count = 0;
for(RealmResults<T> realmResult : realmResults) {
count += realmResult.size();
}
return count;
}
/**
* Returns the item associated with the specified position.
*
* @param i index of item whose data we want.
* @return the item at the specified position.
*/
@Override
public T getItem(int i) {
if (realmResults == null || realmResults.size()==0) {
return null;
}
int count = 0;
for(RealmResults<T> realmResult : realmResults) {
if(i<realmResult.size()+count) {
return realmResult.get(i-count);
}
count += realmResult.size();
}
return null;
}
/**
* Returns the current ID for an item. Note that item IDs are not stable so you cannot rely on the item ID being the
* same after {@link #notifyDataSetChanged()} or {@link #updateRealmResults(List<RealmResults<T>>)} has been called.
*
* @param i index of item in the adapter.
* @return current item ID.
*/
@Override
public long getItemId(int i) {
// TODO: find better solution once we have unique IDs
return i;
}
/**
* Updates the RealmResults associated to the Adapter. Useful when the query has been changed.
* If the query does not change you might consider using the automaticUpdate feature.
*
* @param queryResults the new RealmResults coming from the new query.
*/
public void updateRealmResults(List<RealmResults<T>> queryResults) {
for(RealmResults<T> results : realmResults) {
if(results.isValid()) {
results.removeChangeListener(realmChangeListener);
}
}
this.realmResults = queryResults;
for(RealmResults<T> results : realmResults) {
results.addChangeListener(realmChangeListener);
}
notifyDataSetChanged();
}
}
基本上,我用RealmResults列表替换了单个RealmResult,并修改了getItem()和getCount()方法.
Basically I replaced the single RealmResult with a list of RealmResults and modified the getItem() and getCount() method.
// before
protected RealmResults<T> realmResults;
// after
protected List<RealmResults<T>> realmResults;
这就是我更新搜索的方式
And this is how I update the search
List<RealmResults<Command>> results = new ArrayList<>();
results.add(mRealm.where(Command.class).equalTo("name", query).findAll());
results.add(mRealm.where(Command.class).beginsWith("name", query).notEqualTo("name", query).findAll());
results.add(mRealm.where(Command.class).contains("name", query).not().beginsWith("name", query).notEqualTo("name", query).findAll());
mAdapter.updateRealmResults(results);
这篇关于用于领域中搜索的复杂排序,多个RealmResults的并集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!