有没有办法在Realm中的两个字段中进行条件排序?

时间:2017-07-07 05:30:43

标签: android realm realm-list

我有一个评级领域对象列表如下:

public class RatingRealmObject extends RealmObject {

    @SerializedName("average")
    private float average;
    @SerializedName("raters")
    private int raters;

    public float getAverage() {
        return average;
    }

    public void setAverage(float average) {
        this.average = average;
    }

    public int getRaters() {
        return raters;
    }

    public void setRaters(int raters) {
        this.raters = raters;
    }
}

我想按平均值的降序对RealmResultList进行排序,但是raters的数量应该大于或等于5.

e.g。如果我们有两个食谱作为A和B.

  • A的平均评分为4,没有。评分者是8,

  • B的平均评分为5而没有。评分者是4

然后在排序之后,A应该在列表中排在第一位。

如何在领域查询中创建条件的任何帮助。

3 个答案:

答案 0 :(得分:2)

一种可能的解决方案是将两个RealmResults连接在一起以获得所需的排序,请参阅here

另一种解决方案是,如果使用附加字段扩展架构

public class RatingRealmObject extends RealmObject {
    @Inedx
    private float average;

    private int raters;

    @Index
    private int hasOverFiveRaters; // 0 or 1 like a TINYINT in SQLite

    public float getAverage() {
        return average;
    }

    public void setAverage(float average) {
        this.average = average;
    }

    public int getRaters() {
        return raters;
    }

    public void setRaters(int raters) {
        this.raters = raters;
        this.hasOverFiveRaters = raters >= 5 ? 1 : 0;
    }
}

因为现在you can do

realm.where(RatingRealmObject.class)
     .findAllSortedAsync(
         new String[] {"hasOverFiveRaters", "average"}, 
         new Sort[] { Sort.DESCENDING, Sort.DESCENDING });

PS: realm.copyFromRealm()从Realm中复制每个元素(在您的情况下,在UI线程上)并因此删除延迟评估,除非您是一般的,否则通常不需要也不建议尝试创建一个分离的可修改对象或想要通过GSON发送RealmObject。

答案 1 :(得分:1)

您可以在RatingRealmObject中定义weight字段,并在设置averageraters时计算weight。然后解决方案就像通过public class RatingRealmObject extends RealmObject { private float average; private int raters; @Index private float weight; private void computeWeight() { // This is for showing the idea, you need to change how to calculate the weight depends on your requirement. weight = raters / 5 + average; } public float getAverage() { return average; } public void setAverage(float average) { this.average = average; computeWeight(); } public int getRaters() { return raters; } public void setRaters(int raters) { this.raters = raters; computeWeight(); } } 进行排序一样简单。

一些例子:

realm.where(RatingRealmObject.class).findAllSortedAsync("weight");

然后你可以{{1}}

答案 2 :(得分:0)

@EpicPandaForce和@beeender谢谢你们,你们两个都帮我解决了这个问题。
由于我使用GSON库进行反序列化,因此根据GSON指南,setter方法不会调用。所以Rating对象中的额外字段计算对我来说不起作用。

我已经通过@EpicPandaForce提供的第一个解决方案解决了我的问题。

List<RecipeRealmObject> ratingMoreThan5List = recipeRealmResult.where().greaterThanOrEqualTo("rating.raters", 5).findAllSorted("rating.average", Sort.DESCENDING);
                    List<RecipeRealmObject> ratingLessThan5List = recipeRealmResult.where().lessThan("rating.raters", 5).findAllSorted("rating.average", Sort.DESCENDING);
                    List<RecipeRealmObject> ratingNullList = recipeRealmResult.where().isNull("rating").findAll();

                    List<RecipeRealmObject> recipeList = new ArrayList<>();
                    recipeList.addAll(ratingMoreThan5List);
                    recipeList.addAll(ratingLessThan5List);
                    recipeList.addAll(ratingNullList);
                    onCompleteListener.onSearchComplete(recipeList);