in lucene/src/main/java/org/apache/ofbiz/content/search/ProductDocument.java [146:370]
public Document prepareDocument(Delegator delegator) {
String productId = getDocumentIdentifier().text();
try {
GenericValue product = EntityQuery.use(delegator).from("Product").where("productId", productId).queryOne();
if (product == null) {
// Return a null document (we will remove the document from the index)
return null;
} else {
if ("Y".equals(product.getString("isVariant")) && "true".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.ignore"
+ ".variants", delegator))) {
return null;
}
Document doc = new Document();
Timestamp nextReIndex = null;
// Product Fields
doc.add(new StringField("productId", productId, Field.Store.YES));
addTextField(doc, "productName", product.getString("productName"), false, "fullText", delegator);
addTextField(doc, "internalName", product.getString("internalName"), false, "fullText", delegator);
addTextField(doc, "brandName", product.getString("brandName"), false, "fullText", delegator);
addTextField(doc, "description", product.getString("description"), false, "fullText", delegator);
addTextField(doc, "longDescription", product.getString("longDescription"), false, "fullText", delegator);
doc.add(new LongPoint("introductionDate", quantizeTimestampToDays(product.getTimestamp("introductionDate"))));
nextReIndex = checkSetNextReIndex(product.getTimestamp("introductionDate"), nextReIndex);
doc.add(new LongPoint("salesDiscontinuationDate", quantizeTimestampToDays(product.getTimestamp("salesDiscontinuationDate"))));
nextReIndex = checkSetNextReIndex(product.getTimestamp("salesDiscontinuationDate"), nextReIndex);
doc.add(new StringField("isVariant", product.get("isVariant") != null && product.getBoolean("isVariant") ? "true" : "false",
Field.Store.NO));
// ProductFeature Fields, check that at least one of the fields is set to be indexed
if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductFeatureAndAppl.description", "0", delegator))
|| !"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductFeatureAndAppl.abbrev", "0",
delegator))
|| !"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductFeatureAndAppl.idCode", "0",
delegator))) {
List<GenericValue> productFeatureAndAppls = EntityQuery.use(delegator).from("ProductFeatureAndAppl").where("productId",
productId).queryList();
productFeatureAndAppls = filterByThruDate(productFeatureAndAppls);
for (GenericValue productFeatureAndAppl : productFeatureAndAppls) {
Timestamp fromDate = productFeatureAndAppl.getTimestamp("fromDate");
Timestamp thruDate = productFeatureAndAppl.getTimestamp("thruDate");
if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
// fromDate is after now, update reindex date but don't index the feature
nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
continue;
} else if (thruDate != null) {
nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
}
doc.add(new StringField("productFeatureId", productFeatureAndAppl.getString("productFeatureId"), Field.Store.NO));
doc.add(new StringField("productFeatureCategoryId", productFeatureAndAppl.getString("productFeatureCategoryId"),
Field.Store.NO));
doc.add(new StringField("productFeatureTypeId", productFeatureAndAppl.getString("productFeatureTypeId"), Field.Store.NO));
addTextField(doc, "featureDescription", productFeatureAndAppl.getString("description"), false, "fullText", delegator);
addTextField(doc, "featureAbbreviation", productFeatureAndAppl.getString("abbrev"), false, "fullText", delegator);
addTextField(doc, "featureCode", productFeatureAndAppl.getString("idCode"), false, "fullText", delegator);
// Get the ProductFeatureGroupIds
List<GenericValue> productFeatureGroupAppls = EntityQuery.use(delegator).from("ProductFeatureGroupAppl").where(
"productFeatureId", productFeatureAndAppl.get("productFeatureId")).queryList();
productFeatureGroupAppls = filterByThruDate(productFeatureGroupAppls);
for (GenericValue productFeatureGroupAppl : productFeatureGroupAppls) {
fromDate = productFeatureGroupAppl.getTimestamp("fromDate");
thruDate = productFeatureGroupAppl.getTimestamp("thruDate");
if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
// fromDate is after now, update reindex date but don't index the feature
nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
continue;
} else if (thruDate != null) {
nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
}
doc.add(new StringField("productFeatureGroupId", productFeatureGroupAppl.getString("productFeatureGroupId"),
Field.Store.NO));
}
}
}
// ProductAttribute Fields
if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductAttribute.attrName", "0", delegator))
|| !"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.ProductAttribute.attrValue", "0",
delegator))) {
List<GenericValue> productAttributes =
EntityQuery.use(delegator).from("ProductAttribute").where("productId", productId).queryList();
for (GenericValue productAttribute : productAttributes) {
addTextField(doc, "attributeName", productAttribute.getString("attrName"), false, "fullText", delegator);
addTextField(doc, "attributeValue", productAttribute.getString("attrValue"), false, "fullText", delegator);
}
}
// GoodIdentification
if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.GoodIdentification.idValue", "0", delegator))) {
List<GenericValue> goodIdentifications =
EntityQuery.use(delegator).from("GoodIdentification").where("productId", productId).queryList();
for (GenericValue goodIdentification : goodIdentifications) {
String goodIdentificationTypeId = goodIdentification.getString("goodIdentificationTypeId");
String idValue = goodIdentification.getString("idValue");
doc.add(new StringField("goodIdentificationTypeId", goodIdentificationTypeId, Field.Store.NO));
doc.add(new StringField(goodIdentificationTypeId + "_GoodIdentification", idValue, Field.Store.NO));
addTextField(doc, "identificationValue", idValue, false, "fullText", delegator);
}
}
// Virtual ProductIds
if ("Y".equals(product.getString("isVirtual"))) {
if (!"0".equals(EntityUtilProperties.getPropertyValue("prodsearch", "index.weight.Variant.Product.productId", "0", delegator))) {
List<GenericValue> variantProductAssocs = EntityQuery.use(delegator).from("ProductAssoc").where("productId", productId,
"productAssocTypeId", "PRODUCT_VARIANT").queryList();
variantProductAssocs = filterByThruDate(variantProductAssocs);
for (GenericValue variantProductAssoc : variantProductAssocs) {
Timestamp fromDate = variantProductAssoc.getTimestamp("fromDate");
Timestamp thruDate = variantProductAssoc.getTimestamp("thruDate");
if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
// fromDate is after now, update reindex date but don't index the feature
nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
continue;
} else if (thruDate != null) {
nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
}
addTextField(doc, "variantProductId", variantProductAssoc.getString("productIdTo"), false, "fullText", delegator);
}
}
}
// Index product content
String productContentTypes = EntityUtilProperties.getPropertyValue("prodsearch", "index.include.ProductContentTypes", delegator);
for (String productContentTypeId : productContentTypes.split(",")) {
try {
EntityUtilProperties.getPropertyAsInteger("prodsearch", "index.weight.ProductContent." + productContentTypeId, 1);
} catch (Exception e) {
Debug.logWarning("Could not parse weight number: " + e.toString(), MODULE);
}
List<GenericValue> productContentAndInfos = EntityQuery.use(delegator).from("ProductContentAndInfo").where("productId",
productId, "productContentTypeId", productContentTypeId).queryList();
productContentAndInfos = filterByThruDate(productContentAndInfos);
for (GenericValue productContentAndInfo : productContentAndInfos) {
Timestamp fromDate = productContentAndInfo.getTimestamp("fromDate");
Timestamp thruDate = productContentAndInfo.getTimestamp("thruDate");
if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
// fromDate is after now, update reindex date but don't index the feature
nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
continue;
} else if (thruDate != null) {
nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
}
try {
Map<String, Object> drContext = UtilMisc.<String, Object>toMap("product", product);
String contentText = DataResourceWorker.renderDataResourceAsText(null, delegator, productContentAndInfo.getString(
"dataResourceId"), drContext, null, null, false);
addTextField(doc, "content", contentText, false, "fullText", delegator);
} catch (IOException | GeneralException e1) {
Debug.logError(e1, "Error getting content text to index", MODULE);
}
// TODO: Not indexing alternate locales, needs special handling
/*
List<GenericValue> alternateViews = productContentAndInfo.getRelated("ContentAssocDataResourceViewTo", UtilMisc.toMap
("caContentAssocTypeId", "ALTERNATE_LOCALE"), UtilMisc.toList("-caFromDate"));
alternateViews = EntityUtil.filterByDate(alternateViews, UtilDateTime.nowTimestamp(), "caFromDate", "caThruDate", true);
for (GenericValue thisView: alternateViews) {
}
*/
}
}
// Index the product's directProductCategoryIds (direct parents), productCategoryIds (all ancestors) and prodCatalogIds
this.populateCategoryData(doc, product);
// Index ProductPrices, uses dynamic fields in the format
// ${productPriceTypeId}_${productPricePurposeId}_${currencyUomId}_${productStoreGroupId}_price
List<GenericValue> productPrices = product.getRelated("ProductPrice", null, null, false);
productPrices = filterByThruDate(productPrices);
for (GenericValue productPrice : productPrices) {
Timestamp fromDate = productPrice.getTimestamp("fromDate");
Timestamp thruDate = productPrice.getTimestamp("thruDate");
if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
// fromDate is after now, update reindex date but don't index the feature
nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
continue;
} else if (thruDate != null) {
nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
}
StringBuilder fieldNameSb = new StringBuilder();
fieldNameSb.append(productPrice.getString("productPriceTypeId"));
fieldNameSb.append('_');
fieldNameSb.append(productPrice.getString("productPricePurposeId"));
fieldNameSb.append('_');
fieldNameSb.append(productPrice.getString("currencyUomId"));
fieldNameSb.append('_');
fieldNameSb.append(productPrice.getString("productStoreGroupId"));
fieldNameSb.append("_price");
doc.add(new DoublePoint(fieldNameSb.toString(), productPrice.getDouble("price")));
}
// Index ProductSuppliers
List<GenericValue> supplierProducts = product.getRelated("SupplierProduct", null, null, false);
supplierProducts = filterByThruDate(supplierProducts, "availableThruDate");
Set<String> supplierPartyIds = new TreeSet<>();
for (GenericValue supplierProduct : supplierProducts) {
Timestamp fromDate = supplierProduct.getTimestamp("availableFromDate");
Timestamp thruDate = supplierProduct.getTimestamp("availableThruDate");
if (fromDate != null && fromDate.after(UtilDateTime.nowTimestamp())) {
// fromDate is after now, update reindex date but don't index the feature
nextReIndex = checkSetNextReIndex(fromDate, nextReIndex);
continue;
} else if (thruDate != null) {
nextReIndex = checkSetNextReIndex(thruDate, nextReIndex);
}
supplierPartyIds.add(supplierProduct.getString("partyId"));
}
for (String supplierPartyId : supplierPartyIds) {
doc.add(new StringField("supplierPartyId", supplierPartyId, Field.Store.NO));
}
// TODO: Add the nextReIndex timestamp to the document for when the product should be automatically re-indexed outside of any ECAs
// based on the next known from/thru date whose passing will cause a change to the document. Need to build a scheduled service to
// look for these.
return doc;
}
} catch (GenericEntityException e) {
Debug.logError(e, MODULE);
}
return null;
}