diff --git a/classes/ezfezpsolrquerybuilder.php b/classes/ezfezpsolrquerybuilder.php
index 4577ada4..03857b3d 100644
--- a/classes/ezfezpsolrquerybuilder.php
+++ b/classes/ezfezpsolrquerybuilder.php
@@ -438,6 +438,12 @@ public function buildSearch( $searchText, $params = array(), $searchTypes = arra
implode( ' ', $docTransformerFields) . ' ' .
implode( ' ', $extraFieldsToReturn );
+ // WIP locations as child docs of main content
+ // first add a "parent" filter to the main query
+ $filterQuery[]='meta_doctype_ms:content';
+ // add the child doctransformer
+ $fieldsToReturnString .= ' ' . '[child parentFilter="meta_doctype_ms:content" childFilter="meta_doctype_ms:location"]';
+
if ( ! $asObjects )
{
if ( empty( $fieldsToReturn ))
diff --git a/classes/ezfindresultnode.php b/classes/ezfindresultnode.php
index fafca310..258b84f0 100644
--- a/classes/ezfindresultnode.php
+++ b/classes/ezfindresultnode.php
@@ -18,15 +18,19 @@ function eZFindResultNode( $rows = array() )
$this->ContentObjectID = $rows['id'];
}
$this->LocalAttributeValueList = array();
- $this->LocalAttributeNameList = array( 'is_local_installation',
- 'name',
- 'global_url_alias',
- 'published',
- 'language_code',
- 'highlight',
- 'score_percent',
- 'elevated'
- );
+ $this->LocalAttributeNameList = array(
+ 'is_local_installation',
+ 'name',
+ 'global_url_alias',
+ 'published',
+ 'language_code',
+ 'highlight',
+ 'score_percent',
+ 'elevated',
+ //WIP: for now contains raw dump of child docs returned ... ie all nodes that satisfy
+ // upstream child filter conditions
+ 'children',
+ );
}
/*!
diff --git a/classes/ezsolrdoc.php b/classes/ezsolrdoc.php
index 7f7fb5b1..314c25db 100644
--- a/classes/ezsolrdoc.php
+++ b/classes/ezsolrdoc.php
@@ -22,6 +22,12 @@ class eZSolrDoc
*/
public $Doc = array();
+ /**
+ *
+ * @var array of child documents as eZSolrDoc objects!
+ */
+ public $Children = array();
+
/**
*
* @var numeric
@@ -105,23 +111,25 @@ public function setFieldBoost ($name, $boost)
}
}
+
/**
- * Convert current object to XML string
*
- * @return string XML string.
+ * @param DOMDocument $domDoc The (usually) empty DOM master document
+ * @param mixed $inputArray containing the fields, field values and field boosts
+ * @param Booleam $boost the Lucene overall document boost to apply if any
+ * @return DOMElement The doc and field structure
*/
- function docToXML()
+ public static function createDocElementFromArray( DOMDocument $domDoc, $inputArray = array(), $boost = NULL )
{
- $this->DomDoc = new DOMDocument( '1.0', 'utf-8' );
- $this->DomRootElement = $this->DomDoc->createElement( 'doc' );
- $this->DomDoc->appendChild( $this->DomRootElement );
+ $docRootElement = $domDoc->createElement( 'doc' );
- if ($this->DocBoost !== null && is_numeric( $this->DocBoost ) )
+ if ( $boost !== null && is_numeric( $boost ) )
{
- $this->DomRootElement->setAttribute( 'boost', $this->DocBoost );
+ $docRootElement->setAttribute( 'boost', $boost );
}
- foreach ($this->Doc as $name => $field) {
+ foreach ( $inputArray as $name => $field )
+ {
foreach( $field['content'] as $value )
{
// $value should never be array. Log the value and the stack trace.
@@ -133,19 +141,40 @@ function docToXML()
"\nStack trace: " . var_export( $dump, 1 ) );
continue;
}
- $fieldElement = $this->DomDoc->createElement( 'field' );
- $fieldElement->appendChild( $this->DomDoc->createTextNode( $value ) );
+ $fieldElement = $domDoc->createElement( 'field' );
+ $fieldElement->appendChild( $domDoc->createTextNode( $value ) );
$fieldElement->setAttribute( 'name', $name );
- if ( $field['boost'] !== null && is_numeric( $field['boost'] ) )
+ if ( isset( $field['boost'] ) && is_numeric( $field['boost'] ) )
{
$fieldElement->setAttribute( 'boost', $field['boost'] );
}
- $this->DomRootElement->appendChild( $fieldElement );
+ $docRootElement->appendChild( $fieldElement );
}
}
+ return $docRootElement;
+ }
+ /**
+ * Convert current object to XML string
+ *
+ * @return string XML string.
+ */
+ function docToXML()
+ {
+ $this->DomDoc = new DOMDocument( '1.0', 'utf-8' );
+ $this->DomRootElement = self::createDocElementFromArray( $this->DomDoc, $this->Doc, $this->DocBoost );
+
+ foreach ( $this->Children as $child )
+ {
+ if ( $child instanceof eZSolrDoc )
+ {
+ $this->DomRootElement->appendChild( self::createDocElementFromArray( $this->DomDoc, $child->Doc ) );
+ }
+ }
+
+ $this->DomDoc->appendChild( $this->DomRootElement );
$rawXML = $this->DomDoc->saveXML( $this->DomRootElement );
//make sure there are no control characters left that could currupt the XML string
diff --git a/java/solr/ezp-default/conf/schema.xml b/java/solr/ezp-default/conf/schema.xml
index 55f72553..2dde8a79 100644
--- a/java/solr/ezp-default/conf/schema.xml
+++ b/java/solr/ezp-default/conf/schema.xml
@@ -529,6 +529,7 @@
&customfields;
+
diff --git a/search/plugins/ezsolr/ezsolr.php b/search/plugins/ezsolr/ezsolr.php
index 19c2ae31..425d82e4 100644
--- a/search/plugins/ezsolr/ezsolr.php
+++ b/search/plugins/ezsolr/ezsolr.php
@@ -99,6 +99,29 @@ static function nodeAttributes()
'view_count' => 'sint' );
}
+
+ /**
+ *
+ * @return array additional node attributes which are stored in the nested location child docs
+ */
+ static function additionalNodeAttributes()
+ {
+ return array( 'parent_node_id' => 'mstring',
+ 'main_node_id' => 'mstring',
+ 'parent_node_id' => 'mstring',
+ 'contentobject_id' => 'mstring',
+ 'path_identification_string' => 'mstring',
+ 'remote_id' => 'mstring',
+ 'name' => 'mstring',
+ 'children_count' => 'sint',
+ 'is_main' => 'boolean',
+ 'url' => 'mstring',
+ 'class_identifier' => 'mstring',
+ 'class_name' => 'mstring',
+ 'is_container' => 'boolean',);
+ }
+
+
/**
* Get meta attribute Solr document field type
*
@@ -130,7 +153,8 @@ static function getMetaAttributeType( $name, $context = 'search' )
'visible_path_string' => 'mstring',
'hidden_path_string' => 'mstring' ),
self::metaAttributes(),
- self::nodeAttributes() ),
+ self::nodeAttributes(),
+ self::additionalNodeattributes() ),
'facet' => array(
'owner_name' => 'string' ),
'filter' => array(),
@@ -489,9 +513,18 @@ function addObject( $contentObject, $commit = true, $commitWithin = 0, $softComm
$nodeID = $contentNode->attribute( 'node_id' );
foreach ( eZSolr::nodeAttributes() as $attributeName => $fieldType )
{
- $nodeAttributeValues[$nodeID][] = array( 'name' => $attributeName,
- 'value' => $contentNode->attribute( $attributeName ),
- 'fieldType' => $fieldType );
+ $nodeAttributeValues[$nodeID][$attributeName] = array(
+ 'value' => $contentNode->attribute($attributeName),
+ 'fieldType' => $fieldType);
+ }
+
+ //WIP additional meta info for locations/nodes
+ foreach (eZSolr::additionalNodeAttributes() as $attributeName => $fieldType)
+ {
+ $additionalAttributeValues[$nodeID][$attributeName] = array (
+ 'value' => $contentNode->attribute($attributeName),
+ 'fieldType' => $fieldType);
+
}
$nodePathArray[] = $contentNode->attribute( 'path_array' );
if ( $contentNode->attribute( 'is_hidden' ) || $contentNode->attribute( 'is_invisible' ) )
@@ -561,6 +594,8 @@ function addObject( $contentObject, $commit = true, $commitWithin = 0, $softComm
$doc = new eZSolrDoc( $docBoost );
// Set global unique object ID
$doc->addField( ezfSolrDocumentFieldBase::generateMetaFieldName( 'guid' ), $this->guid( $contentObject, $languageCode ) );
+ // WIP: hardcoded fieldname for now
+ $doc->addField('meta_doctype_ms','content');
// Set installation identifier
$doc->addField( ezfSolrDocumentFieldBase::generateMetaFieldName( 'installation_id' ), self::installationID() );
@@ -604,19 +639,43 @@ function addObject( $contentObject, $commit = true, $commitWithin = 0, $softComm
}
// Set content node meta attribute values.
+ // WIP: initial hack, add children docs here as well
foreach ( $nodeAttributeValues as $nodeID => $metaInfoArray )
{
- foreach( $metaInfoArray as $metaInfo)
+ $doc->Children[$nodeID] = new eZSolrDoc();
+ $doc->Children[$nodeID]->addField( ezfSolrDocumentFieldBase::generateMetaFieldName( 'guid' ), $this->guid( $contentObject, $languageCode, $nodeID ) );
+ // hardcoded field name for now
+ $doc->Children[$nodeID]->addField('meta_doctype_ms','location');
+
+ foreach( $metaInfoArray as $metaInfoName => $metaInfo)
{
- $doc->addField( ezfSolrDocumentFieldBase::generateMetaFieldName( $metaInfo['name'] ),
- ezfSolrDocumentFieldBase::preProcessValue( $metaInfo['value'], $metaInfo['fieldType'] ) );
+ $locFieldName = ezfSolrDocumentFieldBase::generateMetaFieldName( $metaInfoName );
+ $locFieldValue = ezfSolrDocumentFieldBase::preProcessValue( $metaInfo['value'], $metaInfo['fieldType'] );
+ $doc->addField( $locFieldName, $locFieldValue );
+ $doc->Children[$nodeID]->addField('loc_' . $locFieldName, $locFieldValue);
+ }
+ // WIP: add sorting by priority values as a field in the content doc for the respective parent
+ // location (aka node) ids
+ }
+
+ //WIP additional meta data to add to the location child docs
+ foreach ( $additionalAttributeValues as $nodeID => $metaInfoArray )
+ {
+ foreach( $metaInfoArray as $metaInfoName => $metaInfo)
+ {
+ $locFieldName = ezfSolrDocumentFieldBase::generateMetaFieldName( $metaInfoName );
+ $locFieldValue = ezfSolrDocumentFieldBase::preProcessValue( $metaInfo['value'], $metaInfo['fieldType'] );
+ $doc->Children[$nodeID]->addField('loc_' . $locFieldName, $locFieldValue);
}
+ // provide data for sorting according to the the fetch content list way, 1 level deep
+ $doc->addField('loc_priority_for_parent_' . $additionalAttributeValues[$nodeID]['parent_node_id']['value'] . '_i', $nodeAttributeValues[$nodeID]['priority']['value']);
+
}
// Main node gets single valued fields for sorting, using a dedicated prefix
- foreach ( $nodeAttributeValues[$mainNodeID] as $metaInfo )
+ foreach ( $nodeAttributeValues[$mainNodeID] as $metaInfoName => $metaInfo )
{
- $fieldName = 'main_node_' . ezfSolrDocumentFieldBase::generateMetaFieldName( $metaInfo['name'] );
+ $fieldName = 'main_node_' . ezfSolrDocumentFieldBase::generateMetaFieldName( $metaInfoName );
$doc->addField( $fieldName,
ezfSolrDocumentFieldBase::preProcessValue( $metaInfo['value'],
$metaInfo['fieldType'] ) );
@@ -1220,12 +1279,12 @@ static function installationID()
* @param string $languageCode
* @return string guid
*/
- function guid( $contentObject, $languageCode = '' )
+ function guid( $contentObject, $languageCode = '', $locationID = '' )
{
if ( !$contentObject instanceof eZContentObject )
return md5( self::installationID() . '-' . $contentObject . '-' . $languageCode );
- return md5( self::installationID() . '-' . $contentObject->attribute( 'id' ) . '-' . $languageCode );
+ return md5( self::installationID() . '-' . $contentObject->attribute( 'id' ) . '-' . $languageCode . '-' . $locationID );
}
/**
@@ -1696,6 +1755,7 @@ protected function buildResultObjects( $resultArray, &$searchCount, $asObjects =
$emit['highlight'] = isset( $highLights[$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'guid' )]] ) ?
$highLights[$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'guid' )]] : null;
$emit['elevated'] = ( isset($doc['[elevated]']) ? $doc['[elevated]'] === true : false );
+ $emit['children'] = ( isset( $doc['_childDouments_'] ) ) ? $doc['_childDocuments_'] : NULL;
$objectRes[] = $emit;
unset( $emit );
continue;
@@ -1780,6 +1840,7 @@ protected function buildResultObjects( $resultArray, &$searchCount, $asObjects =
$maxScore != 0 ? $resultTree->setAttribute( 'score_percent', (int) ( ( $doc['score'] / $maxScore ) * 100 ) ) : $resultTree->setAttribute( 'score_percent', 100 );
$resultTree->setAttribute( 'language_code', $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'language_code' )] );
$resultTree->setAttribute( 'elevated', ( isset($doc['[elevated]']) ? $doc['[elevated]'] === true : false ) );
+ $resultTree->setAttribute( 'children', ( isset($doc['_childDocuments_']) ? $doc['_childDocuments_'] : NULL ) );
$objectRes[] = $resultTree;
}
}