Realm Query не дает правильных результатов - PullRequest
0 голосов
/ 06 февраля 2019

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

Класс поставщика

public class Provider extends RealmObject {

    @SerializedName("id")
    @PrimaryKey
    public int providerId;
    public String name;
    public RealmList<Product> products;

}

Класс продукта

public class Product extends RealmObject {

    @SerializedName("id")
    @PrimaryKey
    public int productId;
    public String name;
    public RealmList<ProductType> types;

}

Класс типа продукта

public class ProductType extends RealmObject {

    @SerializedName("id")
    @PrimaryKey
    public int productTypeId;
    public String name;
    public Packaging packaging; }

Вот пример JSON того, что загружается в область:

{
  "providers": [{
      "id": 1,
      "name": "PROVIDER_1",
      "products": [{
        "id": 10,
        "name": "Banana",
        "types": [{
            "id": 101,
            "name": "Costa rica",
            "packaging": {
              "isFree": true,
              "value": 0
            }
          },
          {
            "id": 102,
            "name": "Brasil",
            "packaging": {
              "isFree": true,
              "value": 0
            }
          }
        ]
      }]
    },{
      "id": 4,
      "name": "PROVIDER_2",
      "products": [{
        "id": 10,
        "name": "Banana",
        "types": [{
            "id": 103,
            "name": "Ecuador Prem",
            "packaging": {
              "isFree": true,
              "value": 0
            }
          }
        ]
      },
      {
        "id": 21,
        "name": "Apple",
        "types": [{
            "id": 212,
            "name": "Red del",
            "packaging": {
              "isFree": true,
              "value": 0
            }
          }
        ]
      }]
    }

    ]
}

Итак, проблема, с которой я сталкиваюсь, возникает, когда я пытаюсь выбрать типы бананов, используя следующий запрос

RealmResults<Provider> results = mRealm.where(Provider.class).equalTo("providerId", providerId).findAll();
Product product = results.where().equalTo("providerId", providerId).findFirst().products.where().equalTo("productId", productId).findFirst();
RealmList<ProductType> types = product.types;

, список возвращаемых типов всегда дает мне типы второго поставщика.В текущем примере я получаю «Эквадор Прем», даже если я запрашиваю провайдера с идентификатором 1, который равен PROVIDER_1, и этот провайдер должен возвращать типы «Коста-Рика» и «Бразилия».

1 Ответ

0 голосов
/ 07 февраля 2019

У вас есть одна из двух или трех проблем:

1.) Ваш API возвращает, что product type имеет значение id для Banana, но вы получаете id=10;Banana оба для Provider1и Provider2, поэтому Banana, который имеет Provider1, сохраняется, после чего Banana, который имеет Provider2 с тем же идентификатором, сохраняется (и, следовательно, перезаписывает исходный Banana с помощью Provider1 вместо «слияния их»."например).

Таким образом, вместо непосредственного сопоставления ответов API с объектами RealmObject, вы должны ввести составной ключ, вычисляемый вручную, который, скорее всего, является полем String, содержащим оба ProviderID, сцепленные с ProductTypeID.

public class Product extends RealmObject {

    @PrimaryKey
    public String providerWithProductId; // must be set, like "$PROVIDERID_$PRODUCTID"

    @Index
    public int productId;
    public String name;
    public RealmList<ProductType> types;

}

Я надеюсь, что это не область Sync!

2.) Вы непосредственно отображаете объекты JSON в область, возможно, из-за «удобства», но это лишает вас возможности настройкисоставить оптимальную схему для ваших запросов.

На самом деле, «Поставщик» не кажется особенно важным, за исключением того, что конкретный банан принадлежит определенному поставщику;это может быть смоделировано как поле вместо ссылки на объект.

// public class Provider extends RealmObject {
// 
//     @SerializedName("id")
//     @PrimaryKey
//     public int providerId;
//     public String name;
//    public RealmList<Product> products;
// 
// }

public class Product extends RealmObject {

    @PrimaryKey
    public String providerWithProductId; // must be set

    @Index
    public int productId;
    public String productName;

    @Index
    public int providerId;
    public String providerName;

    public RealmList<ProductType> productTypes;

}

Кроме того, packaging - это всего лишь два поля, которые можно легко объединить в ProductType.А также, если тип Ecuador Prem может принадлежать нескольким продуктам и нескольким провайдерам, то он также должен иметь составной ключ, составленный из всех 3-х этих идентификаторов!

public class ProductType extends RealmObject {
    @PrimaryKey
    public String providerWithProductWithProductTypeId; // you must fill this yourself

    @Index
    public int providerId;

    @Index
    public int productTypeId;

    @Index
    public int productId;

    public String productTypeName;

    //public Packaging packaging; 
    public boolean packagingIsFree;

    public long packagingValue;   
}

3.) После получения , что , вы можете легко положиться либо на проверку непосредственно для providerId, также сохраненного в ProductType, либо иным образом на @LinkingObjects, чтобы инвертировать направление вашего запроса.

public class ProductType extends RealmObject {
    @PrimaryKey
    public String providerWithProductWithProductTypeId; // you must fill this yourself

    @Index
    public int providerId;

    @Index
    public int productTypeId;

    @Index
    public int productId;

    public String productTypeName;

    //public Packaging packaging; 
    public boolean packagingIsFree;

    public long packagingValue;   

    @LinkingObjects("productTypes")
    public final RealmResults<Product> isTypeOfProducts = null;
}

После чего вы можете выполнить любой из

// RealmResults<Provider> resultsmRealm.where(Provider.class).equalTo("providerId", providerId).findAll();
// Product product = results.where().equalTo("providerId", providerId).findFirst().products.where().equalTo("productId", productId).findFirst();
// RealmList<ProductType> types = product.types;

RealmResults<ProductType> types = mRealm.where(ProductType.class).equalTo("providerId", providerId).findAll();

// or
RealmResults<ProductType> types = mRealm.where(ProductType.class).equalTo("isTypeOfProducts.providerId", providerId).findAll();

Так что, если это приложение еще не запущено, то полностью пересмотрит вашу схему Realm .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...