Sitecore Lucene search indexing and subfolders - search

How can I make Lucene include results, indexed outside the siteroot eg. stuff based with a root of fx. "/sitecore/content/stuff", but not placed in "/sitecore/content/Home".
Taking a look at SearchManager.cs in "/sitecore modules/LuceneSearch/, the SiteRoot is defined as "SiteCore.Content.Site.Startpath", but making any changes to this file dosent seem to have any affect.
Note:
I am only using the "LuceneResults".ascx & .cs.
----- Question updated, as I narrowed in what the problem might be -----
Im trying to create an index of a specific set of items, for use in a Lucene search.
In web.config, I have specified an index containing:
...
<root>/sitecore/content/Home/Subfolder</root>
...
and that works flawlessly, getting all the subitems when doen a search.
I have then copied exactly the same items to a new location, and updated my web.config as following:
...
<root>/sitecore/content/newSubfolder/Subfolder/Subfolder</root>
...
Now my searches never finds anything!
Does anyone have an idea what could be the problem here.
Note:
- I have rebuild the Search Index db, at every change.
- In "Luke" the index seems fine, and the the search here yields the proper results.
Complete Index:
<index id="faqindex" type="Sitecore.Search.Index, Sitecore.Kernel">
<param desc="name">$(id)</param>
<param desc="folder">__faq</param>
<Analyzer ref="search/analyzer"/>
<locations hint="list:AddCrawler">
<resources type="Sitecore.Search.Crawlers.DatabaseCrawler, Sitecore.Kernel">
<database>master</database>
<root>/sitecore/content/MyContent/Snippets/FAQ</root>
<include hint="list:IncludeTemplate">
<faqblock>{3340AAAE-B2F8-4E22-8B7B-F3EDDB48587E}</faqblock>
</include>
<tags>faqblock</tags>
<boost>1.0</boost>
</resources>
</locations>
</index>

It sounds like you are using the Lucene Search module from Sitecore Marketplace. The code for this module limits the search results to the site root and its children:
public SearchManager(string indexName)
{
SearchIndexName = indexName;
Database database = Factory.GetDatabase("master");
var item = Sitecore.Context.Site.StartPath;
SiteRoot = database.GetItem(item);
}
[...]
public SearchResultCollection Search(string searchString)
{
//Getting index from the web.config
var searchIndex = Sitecore.Search.SearchManager.GetIndex(SearchIndexName);
using(IndexSearchContext context = searchIndex.CreateSearchContext())
{
SearchHits hits = context.Search(searchString, new SearchContext(SiteRoot));
sitecore modules\Lucene Search\SearchManager.cs
Assuming that the "website" node in the sites section of Web.config has startItem="/home", results outside of the "home" hierarchy will not be returned.
If you download the source code for this project, and edit the line that populates SiteRoot to the following, the new items will be returned:
SiteRoote = database.GetItem("/sitecore/content");
Remember to copy the new LuceneSearch.dll to the bin directory of the website project.

Related

Value not reflected on change in ItemCommand within RadGrid

I am having a RadGrid which contains MasterTableView and a DetailView. I am trying to change the value of Sub Total present in MasterTableView on deleting DetailView Row. I am able to get the control in Parent Table and am able to change the value. However value is not reflecting. I tried multiple options e.g. Rebind() method as well as e.Item.OwnerTableView.DataBind(). Here is what my ItemCommand function looks like
Private Sub dbgView_ItemCommand(ByVal source As System.Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) Handles dbgView.ItemCommand
If e.CommandName.ToLower.Equals(GlobalConstants.Key_Delete_CommandName) And e.Item.OwnerTableView.Name = "Tax" Then
dataItem = DirectCast(e.Item.OwnerTableView.ParentItem, GridDataItem)
Dim numSubTotal As NumericBox = dataItem.FindControl("numAmount")
numSubTotal.Text = "New Value"
' e.Item.OwnerTableView.DataBind()
End If
Can someone help me understand why the new value is not reflecting? Here is how my grid looks like
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="dbgView">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="dbgView"></telerik:AjaxUpdatedControl>
</telerik:AjaxUpdatedControl>
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadGrid ID="dbgView" runat="server" AutoGenerateColumns="False" AllowPaging="True"
PageSize="5" GridLines="Horizontal" Skin="Office2010Blue" Style="border: 0 none"
AllowAutomaticInserts="True">
<PagerStyle Mode="NumericPages"></PagerStyle>
<MasterTableView Width="100%" CommandItemDisplay="Top" Name="GLLine" AllowNaturalSort="False"
PageSize="10" DataKeyNames="Key" NoDetailRecordsText="No records to display.">
<DetailTables> .....
UPDATE
On doing further digging i got to know that i need to Rebind the grid post my operation is performed. However while i am performing Rebind, i am getting exception
[HttpException (0x80004005): DataBinding: 'System.Collections.DictionaryEntry' does not contain a property with the name 'TaxID'.]
System.Web.UI.DataBinder.GetPropertyValue(Object container, String propName) +384
Telerik.Web.UI.GridTableView.PopulateDataKey(Object dataItem, DataKey key, String name) +457
Telerik.Web.UI.GridTableView.PopulateDataKeys(Object dataItem) +241
However i don't get this issue during my normal operations. I am able to find out this datakey otherwise for all normal operations. What might be going wrong?
Update
As per below link from Telerik, master table would not be updated when a detail table row is deleted.
http://www.telerik.com/forums/master-grid-not-rebinding-after-detail-table-delete-command
I am trying Rebind exactly mentioned as in this website. However i am getting exception for DataKeyValues as mentioned above. Any pointers would really help.
Issue has been resolved !! I got lot of links which directed me to perform Rebind() operation. However that started creating multiple other issues. This issue was handled by writing a Javascript method handling onclick event of GridButtonColumn by Passing control ids of field from DetailView and Master Table View.

Berkeley XML DB "where" analog

I'm currently studying Berkeley XML DB and got an assignment to write Python script using it. The problem I'm currently facing is to select specific node of container. For example we have container with such information
<root>
<lab>
<name>Lab1</name>
<state>Completed</state>
</lab>
<lab>
<name>Lab3</name>
<state>Not completed</state>
</lab>
</root>
How to select <lab> element with specific <name>? In SQL I'd use WHERE Name='Lab1'. Is there any way to do something like that in XML BDB?
I think you better get old document, copy data, remove document and add new with modified data.
mgr = XmlManager()
uc = mgr.createUpdateContext()
container = mgr.openContainer("labs.dbxml") # Here must be your database name
qc = mgr.createQueryContext()
document = container.getDocument("Lab11")
name = document.getName()
content = document.getContent()
# Change fields here using XPath
container.deleteDocument('La1 1', uc)
container.putDocument(name, content, uc)

How to add section to web config programmatic in SharePoint

I have lot of custom entries to be made in a web config in SharePoint.
Is there a way we can do it programatically.
such as i have
this to add under
<PageParserPath>
<PageParserPath VirtualPath="/*" CompilationMode="Always" AllowServerSideScript="true" IncludeSubFolders="true" />
also i have a complete new section to be added called
<connectionstring>
entries here
</connectionstring>
how can i do it programtically any ideas please
Use SPWebConfigModification:
http://spmatt.wordpress.com/2013/05/22/using-spwebconfigmodification-to-update-the-web-config-in-sharepoint-2013/
In your case you would have something along these lines:
var httpRuntimeModification = new SPWebConfigModification();
httpRuntimeModification.Path = "configuration/PageParserPath";
httpRuntimeModification.Name = "myModification";
httpRuntimeModification.Sequence = 0;
httpRuntimeModification.Owner = "MyAppName";
httpRuntimeModification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNodes;
httpRuntimeModification.Value = "<PageParserPath VirtualPath='/*' CompilationMode='Always' AllowServerSideScript='true' IncludeSubFolders='true' />";
webApp.WebConfigModifications.Add(httpRuntimeModification);
You probably have to tweak the Xpath as I am not sure where this element lives in the web.config
You should use this in a feature receiver where you can get the reference to your webapplication and you should always remove them on feature deactivation

Find in XML and read only that part

I have an XML file with some login information that I need to search for login name, and find relevant data for the account.
The XML file I have looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!--GroupTool2 bot settings file-->
<!--Please do not make any manual changes to this file!-->
<GroupTool2_Settings>
<SavedBots>
<BotName>Midday Ibor</BotName>
<BotPass>Password Hash</BotPass>
<BotMaster>Master Trapper</BotMaster>
<BotGroup>MyGroup</BotGroup>
<StartLocation>#Home/</StartLocation>
<DontSend>1</DontSend>
<DaysBetweenInvited>11</DaysBetweenInvited>
</SavedBots>
<SavedBots>
...
</SavedBots>
</GroupTool2_Settings>
What I need to do, is to be able to search the document for the BotName, and only read the data between that is relevant to the BotName I am searching for.
But there are moe troubles along the way.
The BotName are not always stored as "FirstName LastName", it could also be stored as "FirstName" and "FirstName.LastName"
The variables I will always have aailable to search for, however, is ALWAYS the string BotFName and BotLname. In the cases that the saved BotName is only FirstName, the LastName used will always be a certain name, so the LastName could simply just be dropped when it comes to search for the name in the document.
I am also not the author of the XML document in question, so it can not be changed to simplify my search.
I am however not looking for a full solution, just a short pseudo example so I know where to begin.
Any help is apreciated.
/Rickard
You may search an element via Linq-XML.
XDocument doc = XDocument.Load(file);
string search="Midday Ibor";
var savedBots = doc.Descendants("SavedBots").Where(p => p.Element("BotName").Value == search).FirstOrDefault();
if (savedBots != null)
{
Console.WriteLine((string)savedBots.Element("BotPass"));
}

Magento observer (sales_order_grid_collection_load_before), filter collection by a product attribute

So I'm working with sales_order_grid_collection_load_before observer event at the moment, where I can get the collection being used through $collection = $observer->getEvent()->getOrderGridCollection();, I'm just wondering, if it is possible to filter this collection by a product from the order attribute.
What I mean with that is the order grid collection has sub products related to that order, I need to only show orders if at least one of the products match a specific criteria (in my case, I've given the products an admin_id attribute, which is set to the administrator who added the product).
Thanks!
I've done a very similar thing by doing the following:
Override the sales order grid block. To do this you will need to set up your own extension (it looks like you might already be doing this, but just in case, there is some handy doco in the Magento wiki)
<config>
<modules>
<Company_Module>
<version>0.1.0</version>
</Company_Module>
</modules>
<global>
<blocks>
<company_module>
<class>Company_Module_Block</class>
</company_module>
<adminhtml>
<rewrite>
<sales_order_grid>Company_Module_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
</config>
I then copied the /app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php into my extensions folder at /app/code/local/Company/Module/Block/Sales/Order
In the copied file I changed the class name to class Company_Module_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid
I then changed the _prepareCollection function. In this case I was interested in grabbing the customer_group_id and customer_email from the sales_flat_order table
protected function _prepareCollection() {
$collection = Mage::getResourceModel($this->_getCollectionClass());
// left join onto the sales_flat_order table, retrieving the customer_group_id and customer_email columns -< this can be expanded
$collection->getSelect()->join('sales_flat_order', 'main_table.entity_id=sales_flat_order.entity_id', array('customer_group_id'=>'customer_group_id', 'customer_email'=>'customer_email'), null, 'left');
// grab the current user and get their associated customer groups (additional coding required to associate the customer groups to an admin user
$user = Mage::getSingleton('admin/session')->getUser();
$roleId = implode('', $user->getRoles());
$customerGroupIds = Mage::getModel('admin/roles')->load($roleId)->getCustomerGroupIds();
$orders = Mage::getResourceModel('sales/order_collection');
// if the admin user has associated customer group ids then find the orders associated with those
// this would be where you would do your filtering of the products
if (count($customerGroupIds)) {
$orders->addAttributeToFilter('customer_group_id', array('in' => $customerGroupIds));
}
$orderIds = $orders->getAllIds();
$collection->addAttributeToFilter('entity_id', array('in' => $orderIds));
$this->setCollection($collection);
return parent::_prepareCollection();
}
You may not need the join to the sales_flat_order table...you might be able to do it just by doing the filtering in the second part of the _prepareCollection function shown above. In my case, I was displaying the customer_group_id and the customer_email in the grid so that the user could manually filter, if required.
I am not sure if you can access directly the product from the order_grid_collection (I don't think so) but you can join this collection with sales_flat_order_item and then filter as you wish.
HTH

Resources