2

我试图在 Commercetools 平台中获取产品所属的所有类别的名称。

我可以通过以下调用获取与产品相关的每个类别的唯一 ID:

final ProductProjectionQuery query = ProductProjectionQuery.ofCurrent();
    ProductProjectionQuery q = query.withLimit(450);

    try {
        PagedQueryResult<io.sphere.sdk.products.ProductProjection> pagedQueryResult = client.execute(q).toCompletableFuture().get();
        List<io.sphere.sdk.products.ProductProjection> products = pagedQueryResult.getResults();

        //createDocument(products.get(0).getMasterVariant(), request);

        for (io.sphere.sdk.products.ProductProjection product : products) {
            String categoryId = product.getCategories().iterator().next().getId();
            //createDocument(product.getMasterVariant(), request);
        }
    }

虽然一旦我有了 categoryId,我不确定如何访问类别名称。我认为 obj 属性可能允许我深入了解该类别,但 obj 变量似乎总是为null

4

1 回答 1

4

The obj variable is null because you have not expanded the reference. Unless you explicitly request it, all references will be empty to improve performance. In order to expand it, you can use this code:

// Query products
final ProductProjectionQuery query = ProductProjectionQuery.ofCurrent()
        .withExpansionPaths(product -> product.categories()) // Request to expand categories
        .withLimit(450);
final List<ProductProjection> products = client.execute(query).toCompletableFuture().join().getResults();

for (ProductProjection product : products) {
    final List<LocalizedString> categoryLocalizedNames = product.getCategories().stream()
            .map(categoryRef -> categoryRef.getObj().getName())
            .collect(toList());
    // Do something with categoryLocalizedNames
}

But I strongly recommend you to cache the categories in a CategoryTree instance and grab the name from it, because otherwise the performance will be quite affected by expanding all categories of each product. Here is the code:

// Query all categories and put them in a CategoryTree
final CategoryQuery queryAllCategories = CategoryQuery.of().withLimit(500);
final List<Category> allCategories = client.execute(queryAllCategories).toCompletableFuture().join().getResults();
final CategoryTree categoryTree = CategoryTree.of(allCategories);

// Query products
final ProductProjectionQuery query = ProductProjectionQuery.ofCurrent().withLimit(500);
final List<ProductProjection> products = client.execute(query).toCompletableFuture().join().getResults();

for (ProductProjection product : products) {
    final List<LocalizedString> categoryLocalizedNames = new ArrayList<>();
    product.getCategories().forEach(categoryRef -> {
        final Optional<Category> categoryOpt = categoryTree.findById(categoryRef.getId());
        if (categoryOpt.isPresent()) {
            categoryLocalizedNames.add(categoryOpt.get().getName());
        }
    });
    // Do something with categoryLocalizedNames
}

Of course that means you also have to find a solution to invalidate the cached categories when they change.

于 2016-01-04T12:13:21.080 回答