Querying Data in B2C Commerce Efficient data querying is critical for storefront performance and job stability. B2C Commerce provides index-backed search APIs and database query APIs—choosing the right one for each use case avoids performance problems. Product Search (Storefront) Use ProductSearchModel for all storefront product searches. It is index-backed and designed for high-traffic pages. Basic Product Search var ProductSearchModel = require ( 'dw/catalog/ProductSearchModel' ) ; var psm = new ProductSearchModel ( ) ; psm . setCategoryID ( 'electronics' ) ; psm . setOrderableProductsOnly ( true ) ; // Only in-stock products psm . setSearchPhrase ( 'laptop' ) ; psm . search ( ) ; var hits = psm . getProductSearchHits ( ) ; while ( hits . hasNext ( ) ) { var hit = hits . next ( ) ; var productID = hit . productID ; var minPrice = hit . minPrice ; var maxPrice = hit . maxPrice ; } hits . close ( ) ; Paging Search Results Always page results—never load the full result set: var ProductSearchModel = require ( 'dw/catalog/ProductSearchModel' ) ; var PagingModel = require ( 'dw/web/PagingModel' ) ; var psm = new ProductSearchModel ( ) ; psm . setCategoryID ( 'mens-clothing' ) ; psm . setOrderableProductsOnly ( true ) ; psm . search ( ) ; var pagingModel = new PagingModel ( psm . getProductSearchHits ( ) , psm . count ) ; pagingModel . setPageSize ( 12 ) ; pagingModel . setStart ( 0 ) ; // page offset var pageElements = pagingModel . pageElements ; while ( pageElements . hasNext ( ) ) { var hit = pageElements . next ( ) ; // Render product tile } Getting Variation Data from Search Hits Use ProductSearchHit methods instead of loading full product objects: // GOOD: Get variation info from the search hit (index-backed) var representedColors = hit . getRepresentedVariationValues ( 'color' ) ; var representedIDs = hit . getRepresentedProductIDs ( ) ; var minPrice = hit . getMinPrice ( ) ; var maxPrice = hit . getMaxPrice ( ) ; // BAD: Loading the full product and iterating variants (database-intensive) var product = hit . product ; var variants = product . getVariants ( ) ; // Expensive! var priceModel = product . getPriceModel ( ) ; // Expensive! Search Refinements var psm = new ProductSearchModel ( ) ; psm . setCategoryID ( 'shoes' ) ; psm . addRefinementValues ( 'color' , 'blue' ) ; psm . addRefinementValues ( 'size' , '10' ) ; psm . setPriceMin ( 50 ) ; psm . setPriceMax ( 200 ) ; psm . search ( ) ; // Get available refinement values for the current result set var refinements = psm . getRefinements ( ) ; var colorValues = refinements . getNextLevelRefinementValues ( refinements . getRefinementDefinitionByName ( 'color' ) ) ; ProductSearchModel API Summary Method Description search() Execute the search setCategoryID(id) Filter by category setSearchPhrase(phrase) Set search keywords setOrderableProductsOnly(flag) Exclude out-of-stock addRefinementValues(name, value) Add refinement filter setPriceMin(price) / setPriceMax(price) Price range filter setSortingRule(rule) Set sorting rule getProductSearchHits() Get result iterator getRefinements() Get available refinements count Total result count Order Queries OrderMgr.searchOrders / queryOrders Use searchOrders for index-backed order lookups and queryOrders for database queries: var OrderMgr = require ( 'dw/order/OrderMgr' ) ; var Order = require ( 'dw/order/Order' ) ; // Index-backed search (preferred for common lookups) var orders = OrderMgr . searchOrders ( 'customerEmail = {0} AND status != {1}' , 'creationDate desc' , 'customer@example.com' , Order . ORDER_STATUS_FAILED ) ; while ( orders . hasNext ( ) ) { var order = orders . next ( ) ; // Process order } orders . close ( ) ; // Always close iterators Query by Date Range var OrderMgr = require ( 'dw/order/OrderMgr' ) ; var Calendar = require ( 'dw/util/Calendar' ) ; var Order = require ( 'dw/order/Order' ) ; var startDate = new Calendar ( ) ; startDate . add ( Calendar . DAY_OF_YEAR , - 7 ) ; var orders = OrderMgr . searchOrders ( 'creationDate >= {0} AND status = {1}' , 'creationDate desc' , startDate . time , Order . ORDER_STATUS_NEW ) ; while ( orders . hasNext ( ) ) { var order = orders . next ( ) ; // Process } orders . close ( ) ; searchOrders vs queryOrders Aspect searchOrders queryOrders Backing Search index Database Performance Fast for indexed fields Slower, full table scan possible Use when Querying indexed attributes (status, email, dates) Querying non-indexed or custom attributes Result limit Up to 1000 hits No hard limit (but use paging) Prefer searchOrders for storefront and high-traffic code paths. Use queryOrders only when you need to query attributes not available in the search index. Customer / Profile Queries CustomerMgr (Preferred) Use searchProfiles for index-backed searches and processProfiles for batch processing in jobs: var CustomerMgr = require ( 'dw/customer/CustomerMgr' ) ; // Index-backed search (storefront use) var profiles = CustomerMgr . searchProfiles ( 'email = {0}' , 'lastLoginTime desc' , 'customer@example.com' ) ; while ( profiles . hasNext ( ) ) { var profile = profiles . next ( ) ; // Process profile } profiles . close ( ) ; Batch Processing (Jobs) Use processProfiles for jobs that need to iterate over many profiles—it has optimized memory management: var CustomerMgr = require ( 'dw/customer/CustomerMgr' ) ; function processProfile ( profile ) { // Process each profile individually // Memory is managed automatically } // Process all profiles matching the query CustomerMgr . processProfiles ( 'gender = {0}' , processProfile , 1 ) ; Important: processProfiles replaces the older queryProfiles and SystemObjectMgr.querySystemObjects for customer data. It uses the full-text search service with better performance and memory characteristics. Customer Query Behaviors Wildcards ( * , % , + ) are filtered from queries and replaced by spaces LIKE and ILIKE execute as full-text queries (match whole words, not substrings) LIKE is case-insensitive Combining AND and OR in the same query degrades performance Range queries (e.g., a > b ) impact performance Results are limited to the first 1000 hits System Object Queries (SystemObjectMgr) For querying system objects other than customers (e.g., SitePreferences, catalogs): var SystemObjectMgr = require ( 'dw/object/SystemObjectMgr' ) ; // Query system objects var results = SystemObjectMgr . querySystemObjects ( 'Profile' , 'custom.loyaltyTier = {0}' , 'lastLoginTime desc' , 'Gold' ) ; while ( results . hasNext ( ) ) { var obj = results . next ( ) ; // Process } results . close ( ) ; Note: For customer profiles specifically, prefer CustomerMgr.searchProfiles or CustomerMgr.processProfiles over SystemObjectMgr.querySystemObjects —they use the search index and perform significantly better. Database-Intensive APIs to Avoid These APIs hit the database directly and are expensive on high-traffic pages. Replace them with index-friendly alternatives. See Performance-Critical APIs for the complete list with impact details. Avoid (Database-Intensive) Use Instead (Index-Friendly) Category.getProducts() / getOnlineProducts() ProductSearchModel.setCategoryID() ProductMgr.queryAllSiteProducts() ProductSearchModel.search() Product.getVariants() / getVariationModel() ProductSearchHit methods Product.getPriceModel() (in loops) ProductSearchHit.getMinPrice() / getMaxPrice() CustomerMgr.queryProfiles() CustomerMgr.searchProfiles() or processProfiles()
b2c-querying-data
安装
npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill b2c-querying-data