领域查询未给出正确的结果

问题描述 投票:0回答:1

我有以下数据结构,其中包含提供商列表,包含产品,每个产品都有不同的类型

提供者类

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
            }
          }
        ]
      }]
    }

    ]
}

因此,当我尝试使用以下查询获取Bananas类型时,会出现我遇到的问题

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;

返回的类型列表总是给我第二个提供者的类型。在当前示例中,即使我请求提供者ID为PROVIDER_1,我也会收到“Ecuador Prem”,并且该提供者必须返回“Costa rica”和“Brasil”类型。

android realm
1个回答
1
投票

你有两个或三个问题之一:

1.)你的API返回product typeidBanana,但是你得到了Provider1和Provider2的id=10;Banana,因此保存了BananaProvider1,之后保存了具有相同ID的BananaProvider2(因此用Banana覆盖原始的Provider1而不是“合并它们”(例如)。

因此,不应直接将API响应映射到RealmObjects,而是应该引入一个手动计算的复合键,它很可能是一个String字段,其中包含与ProductTypeID连接的ProviderID。

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;

}

我希望这不是同步领域!

2.)您正在将JSON对象直接映射到Realm,可能是出于“方便”,但这使您无法为查询设置最佳模式。

实际上,除了特定香蕉属于某个提供者之外,“提供者”似乎并不特别重要;这可以建模为字段,而不是对象链接。

// 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类型可以属于多个产品和多个提供者,那么它还应该具有由所有这三个ID构建的复合键!

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架构。

© www.soinside.com 2019 - 2024. All rights reserved.