Improve Content Authors Experience in Sitecore

Sitecore site that is easy to use for Editors, developers and users is considered as best Implementation, we should always consider content editors while designing Sitecore, because any change afterwords can results in lot of back and forth and cost as well.

Sitecore

I would like to share my thoughts based on real time experience, and i think we should try to consider these in every project from beginning.

  • Experience Editor : Sitecore setup cannot be considered as complete or good, unless all the components are Experience Editor (Page Editor)friendly, this includes:
    1. Should be able to add components and datasource.
    2. Making sure components can be moved.
    3. Should be able to set the personalization.
    4. Should be able to configure test.
    5. Proper configuration of placeholders, which takes care of adding relevant components in proper section of the page.
    6. Edit page metadata.
    7. Editor should be able to add field values from Experience editor like (background Image, multi-list fields and etc)

A fully functional experience editor page is the first sign which shows your commitment towards client and quality of your delivery, and same time you are also making use of Sitecore at it’s best.

  •  Insert Rules: 
    1. Insert rules helps establishing information architecture of content tree, which increases consistency, with Insert rules you can restrict what content types can be added under specific location of content tree, which helps in defining scope and helps running queries as well.
    2. We can go to Configure -> Assign and set the Insert options, we also have a way to dynamically define it by using “Insert Option Rules“.
    3. Insert rules helps your content author, and guide them how and what can be added into specific location of content tree, this will help reducing any type of content error in the site, assist developers to define scope while writing programs which makes your code more stable.
  • Standard Values:  The standard values item is an item of the given template type, which will be used to hold the default field values.
    1. By defining default values we can make sure to pre-populate  the standard field values, so that content authors doesn’t have to populate it over and over again.
    2. We can set the default values explicitly, or use of token is a also a great way to populate the values.
    3. We can populate following fields every time when new item gets created in Sitecore:
      1. Title
      2. Description
      3. Date (if exists)

This a great way to help content authors to give them a feel that page doesn’t looks incomplete while adding a new page to content tree, and editors can of course go back and change the default values if required, you can configure default data sources for you renderings in required.

  • Help text : How content authors are comfortable with Sitecore, determines if your Implementation is successful, so, as a developer we always have to think about content author experience, and that should be our high priority.
    1. We should make sure field labels are optimized in such a way they serve the needs of both the developer as well as the content editors, we can achieve this following three ways:
      1. Title
      2. Short description and
      3. Help link
    2. The title field and the short description of a field item enable us to provide the content editor with useful information and have a technical field name for developers to work with.
    3. If you go to specific field item in Sitecore, you can set these values which helps content authors in understanding what this field is meant for, and what value should be added.
  • Clean Sitecore tree:
    1. A clean Information structure helps in making Site more consistent, and we should always remember that site will be used by content editors and not by developers, so it should be as clean as possible.
    2. A new content editor, who just joined the team shouldn’t find any difficulty understanding the site, and it’s component structure.
    3. Good information architecture is a key to successful Sitecore Implementation and maintenance.
  • Components/placeholder configuration(s):
    1. Proper configuration should be done for placeholders, so that content authors can add only those components which are meat for specific placeholder, this way we can make sure to maintain the design, and can prevent any sort of compatibility issues with the page.
    2. We can use allowed control that exists on the placeholder level, which defines the list of component(s) which can be added.
    3. Also, on each rendering we should define “datasource location” and “datasource template” which helps content authors to understand that these data items are compatible for specific rendering(s).
  • Thumbnail for Renderings:
    1. We should try to add thumbnails for all renderings, so that content authors can visualize that what rendering is meant for what, if there are no thumbnails added, it can creates a confusion to content editors, in case if no friendly names has been given to renderings.
    2. If friendly name has been given, it still makes more sense and add value to assign thumbnails.

As a Sitecore consultant and developer, we should keep an eye on every part of your solution from day 1, this helps you in understanding the system as a whole, and also gives you an opportunity to make sure that best practices has been followed while developing the solution,and also that we are using Sitecore features at it’s best.

I hope this helps somebody.

Happy learning 🙂

Advertisements

fixing end of string expected at position error in Sitecore

Recently while verifying some of the components in Experience Editor, I observed that while adding datasource to the renderings, it was throwing “End of string expected at position 75” error.

I checked following things to troubleshoot the issue:

  1. If Datasource location specified in the rendering exists or not, and it exists.
  2. If Datasource template is defined in rendering or not, and it was there.
  3. Check the errors in log file, and there was an error there, please see the below screen shot what error it was.log
  4. Following error was visible in front end while adding datasource.end-of-string-error

 

It turns out Sitecore doesn’t like hyphens “-” in query path, and few other which includes:

  1. If you query contains keyword “and
  2. If query contains keyword “or
  3. If query contains hyphen “

In my case when i checked the query and it contains keyword “and“, which was basically failing and not allowing me to add  datasource from Experience editor.

Solution:

In order to fix this issue we can add escape character “#” before and after of the items that contains any of these keywords or hyphen “-“, so, for example:

Before : query:./ancestor::*[@@templatename=’SitecoreRoot’]/Global//Modules/Image and Media Module

After : query:./ancestor::*[@@templatename=’SitecoreRoot’]/Global//Modules/#Image and Media Module#

After making this change, the issue was fixed.

It seems this issue was there in Sitecore 6, but it can be replicated in Sitecore 8.1 (rev 160302) as well.

I have raised this with Sitecore support team, and they have registered this as Wish/Feature, so, we may see this issue resolved in coming product versions.

I hope this helps somebody.

Happy learning 🙂

http://sdn.sitecore.net/Reference/Using%20Sitecore%20Query/Sitecore%20Query%20Syntax.aspx

 

Test changes without publishing to web DB in Sitecore

In your development environment, did you ever felt that publishing is not providing a great value, but acting like a hindrance?

PublishItem

In Sitecore you can directly test your changes without publishing your changes to web DB, and configure Sitecore to use content from master DB.
This can be done in two ways:

  1. If you don’t have any custom Site configuration config file exist, please go to App_Config/Include/LiveMode.config.example file and rename it to LiveMode.config or
  2. If you have custom Site configuration file exists, you can change the database value to “master” from “web”.

Please make sure to revert your changes, before deploying the solution to QA or production environment.

Happy learning 🙂

 

Versioned-Unversioned and Shared fields in Sitecore

This blog contains information about items, more importantly languages of items, versions of items in languages, and sharing the values of individual item in different supported languages and numbered versions.

This post is focused on explaining the differences between Versioned,Unversioned and shared fields in Sitecore.

Versioning of an item is controlled in three ways:

  1. Versioned fields
  2. Unversioned fields and
  3. Shared fields

VersionedFields

Versioned fields:

By default all the fields are versioned, which means the the field value will be different across different numberd versions and different language versions as well,
example of numbered version-  title/description and etc, or any such field whose field will be different across different languages/versions.

Unversioned fields:

There are certain fields whose value is same for all the numbered versions for a specific language, such as “Country Name”, “Employee Name” and etc, if we want to have such configuration, we should make that field as “Unversioned” in template definition.
When this(“Unversioned”)  checkbox is selected, the field has the same value for every numbered version within a language, but may have different values between supported languages.

Shared fields:

When the field value doesn’t change across languages and number versions, we should mark that field as shared, shared field value will be common across supported languages and versions.
When the Shared property is set, changes to the field value in any language or numbered version of the item will be reflected in all the other language versions and numbered versions.Example- “Id” or some unique identifier which will be commons across languages and versions.

I hope this helps someone in understanding the core concepts and versioned fields.

Please let me know your feedback, or your thoughts on the same.

Happy learning 🙂

Securing Sitecore connection strings

There are scenarios where we don’t want to compromise with the security of our application resources, this includes Connectionstring.config file as example, If someone compromised CD servers, they will have access to Connection string file and can use the details in a wrong way.

There are ways we can secure the connection string in Sitecore, in this blog post I would like to give an example of one of the approach which can be used:

Please see the sample code snippet, to encrypt and decrypt  connection string file.

Configuration config = WebConfigurationManager.OpenWebConfiguration(“~”);

// Get the connectionStrings section.
ConnectionStringsSection section = config.GetSection(“connectionStrings”) as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
}
else
{
section.SectionInformation.ProtectSection(“DataProtectionConfigurationProvider”);
}
// Save changes to the Web.config file.
config.Save();

Few points to note and consider:

  • This approach uses System.Web.Configuration namespace to work.
  • We access application’s web.config file via OpenWebConfiguration method.
  • We access connectionStrings section of the web.config file via GetSection method.
  • Encrypt and decrypt the sections.
  • Save the changes.

This is how the connection string.config file looks before encryption:

<?xml version=”1.0″ encoding=”utf-8″?>
<connectionStrings>
<!–
Sitecore connection strings.
All database connections for Sitecore are configured here.
–>
<add name=”core” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Core” />
<add name=”master” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Master” />
<add name=”web” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Web” />
<add name=”analytics” connectionString=”mongodb://localhost/analytics” />
<add name=”tracking.live” connectionString=”mongodb://localhost/tracking_live” />
<add name=”tracking.history” connectionString=”mongodb://localhost/tracking_history” />
<add name=”tracking.contact” connectionString=”mongodb://localhost/tracking_contact” />
<add name=”reporting” connectionString=”user id=user;password=password;Data Source=(server);Database=Sitecore_Analytics” />
</connectionStrings>

After encryption, this is how the file looks:

<?xml version=”1.0″ encoding=”utf-8″?>
<connectionStrings configProtectionProvider=”DataProtectionConfigurationProvider”>
<EncryptedData>
<CipherData>
<CipherValue>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</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>

If we want to decrypt the section, we can use UnprotectSection()  and can review the connections, once we are good we can again encrypt the setting using ProtectSection() method.

We can also secure the setting using aspnet_regiis.exe tool.

I hope this helps someone, who is looking for something similar, please let me know for any questions on this, happy to discuss more.

Happy learning 🙂

MongoDB authentication in Sitecore

Securing application data is critical for any client and business, and the same principle applies to Sitecore application as well.

One of the most important component of Sitecore is MongoDB, which is where we store all Experience(xDB) related data, MongoDB was shipped into Sitecore’s ecosystem from Sitecore 7.5, and it’s very important to make sure the data stored in xDB is secured, and only authorized uses has access to the data.

Recently, we heard about thousands of MongoDB data being hacked, so what’s the reason behind it? any guess? it’s simple- all those DBs were not configured to be secure and anyone can access it.

It would be great if MongoDB installation itself comes with an option, where we can secure our data while installing it, like how we do it for SQL.

Even though, we can go back and secure the data  by setting up users/roles and permissions, but it’s always great to do it it first place.

We also have to see and make sure that Connection string used for MongoDB is all protected with credentials, so that only authorized users can access it.

As part of this blog post, i would like to cover the steps which we can follow and make our Sitecore application more secure.

  1. Create MongoDB User
    1. Follow the below command to create the user.
    2. db.createUser({user: “mongoadmin”,pwd: “mongoadmin”,roles: [ { role: “userAdminAnyDatabase”, db:”admin” },{ role: “root”, db:”admin” }]})
    3. We just created a new mongouser- “mongoadmin” under database “admin”, and has given all rights to this user by assigning role “root“.
  2. Verifying the User
    1. If we want to verify that user gets created or not, we can use the following command for the same:
    2. db.auth(“mongoadmin”,”mongoadmin”)
    3. This should return 1, if the user is authenticated.
    4. We can also see the list of all users by running following command:
    5. db.getUsers()
  3. Assigning specific roles to unique collections
    1. We shouldn’t be giving “root” level access to the user, and it should be more specific to the database and collection.
    2. For example: we can give read and write access to analytics database in Sitecore.
    3. In order to do that, please login to mongo shell and switch to admin.
    4. use analytics
      db.createUser({user: “mongouser”,pwd: “mongopassword”,roles: [ { role: “readWrite“, db:”analytics” }]})

    5. In this case we created a new user called “mongouser” and assigned “readWrite” role to it, and is specific to “analytics” database.
    6. In the same way, we can do it for other three databases also.
  4. Connection string updates
    1. This is how the default connection string looks like:
    2. <add name=”analytics” connectionString=”mongodb://localhost:27017/sample_analytics” />
      <add name=”tracking.live” connectionString=”mongodb://localhost:27017/sample_tracking_live” />
      <add name=”tracking.history” connectionString=”mongodb://localhost:27017/sample_tracking_history” />
      <add name=”tracking.contact” connectionString=”mongodb://localhost:27017/sample_tracking_contact” />

    3. After making updates to connection string, and adding required username and password details to it, this is how it looks:
    4. <add name=”analytics” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_analytics?authSource=admin” />
      <add name=”tracking.live” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_live?authSource=admin” />
      <add name=”tracking.history” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_history?authSource=admin” />
      <add name=”tracking.contact” connectionString=”mongodb://mongoadmin:mongoadmin@localhost:27017/sample_tracking_contact?authSource=admin” />

    5. This is how the format looks like:
    6. mongodb//[username:password@]host[:port]/database?authSource

If we are trying to access MongoDB without passing valid credentials, we get this error in the log, please see the screen shot for ref:

MongoAuthenticationFailed

Once we pass the valid credentials, this error will go off.

It’s always a good practice to authenticate MongoDB in local environment as well, this helps us in setting the habit for it and we can uncover any issues well in advance.

I hope this helps in getting the understanding about how we can secure and authenticate MongoDB, and how to create users/permissions for the same.

There is a great article in MongoDB documentation, around setting up auth for Mongo and setting up users, creating roles for the same, please consider reviewing this as well, this is great source of information.

https://docs.mongodb.com/manual/tutorial/enable-authentication/

Thanks, and please let me know for any questions, happy to discuss more.

Happy learning 🙂

Changing data directory for MongoDB in Sitecore

As part of my MongoDB Blog series part 1, we discussed how we can Install MongoDB and we used “C” drive as default Installation location for it.

But as a best practice and considering scalable environment, we shouldn’t be using “C” drive to store any application data, it should be reserved only for system files, so that if we need to upgrade the OS or need to repair existing Installation, our application data is still safe.

We have done this for one of the implementation, and it’s always better to do this in early phase of the development.

We can always go back and change the default data directory location for MongoDB in Sitecore, and can use mongo config file which we created for Installing MongoDB.(Please refer MongoDB Blog series part-1 for more details)

This is how it was before:

mongoconfig

Let’s use another drive to store data and logs for MongoDB, in this case it’s “G

mongoconfigrevised

From the above screenshot we can see that, the data and log folder points to “G” drive now, and rest of the configuration is all same.

If you Installed MongoDB as a service, your service still points to “C” drive, but your data and log will be stored in “G” drive.

If you want to copy over existing data from “C” to “G” (in this example), make sure to stop your service, copy your data from “C” to “G”(in this example) and restart MongoDB Service.

This is good from maintenance perspective, and easy to manage afterwards.

I hope this helps someone, who is looking for something similar.

Thanks, and please let me know for any questions and any feedback, happy to discuss more.

Happy learning 🙂

Sitecore MongoDB Blog series: Part 3-Creating custom contact facets

In previous blog post, we gone through introduction of MongoDB with Sitecore which includes scaling, contacts and understanding MongoDB queries.

In this blog post we will go through and understand, how to create a custom contact facet and how to deploy it to Sitecore.

By default there are facets which Sitecore uses, and you can find the details here:

\App_Config\Include\Sitecore.Analytics.Model.Config

<entities>
<contact>
<factory type=”Sitecore.Analytics.Data.ContactFactory, Sitecore.Analytics” singleInstance=”true” />
<template type=”Sitecore.Analytics.Data.ContactTemplateFactory, Sitecore.Analytics” singleInstance=”true” />
<facets>
<facet name=”Personal” contract=”Sitecore.Analytics.Model.Entities.IContactPersonalInfo, Sitecore.Analytics.Model” />
<facet name=”Addresses” contract=”Sitecore.Analytics.Model.Entities.IContactAddresses, Sitecore.Analytics.Model” />
<facet name=”Emails” contract=”Sitecore.Analytics.Model.Entities.IContactEmailAddresses, Sitecore.Analytics.Model” />
<facet name=”Phone Numbers” contract=”Sitecore.Analytics.Model.Entities.IContactPhoneNumbers, Sitecore.Analytics.Model” />
<facet name=”Picture” contract=”Sitecore.Analytics.Model.Entities.IContactPicture, Sitecore.Analytics.Model” />
<facet name=”Communication Profile” contract=”Sitecore.Analytics.Model.Entities.IContactCommunicationProfile, Sitecore.Analytics.Model” />
<facet name=”Preferences” contract=”Sitecore.Analytics.Model.Entities.IContactPreferences, Sitecore.Analytics.Model” />
</facets>
</contact>
</entities>

In this specific example, we will show how to add a custom string value to existing contact card, we can call this Facet “Education

In order to create a custom Facet, we need following components:

  1. Interface (that’s used to create a contract/facet)
  2. Implementation
  3. Configuring the system to use new Facet.

Interface:

Education is the Facet, and the Education property we define for this is Element for this Facet,so we need to create Facet and Element interface.

Here is IProfileEducationFacet Interface, this should inherit IFacet.

IProfileFacet

Next step is to create IProfileEducationElement Interface, here is the sample snippet for the same:

IProfileEducationElement

Implementation:

Once we have Interfaces created for Facet and Element, next step will be to create class that can implement those interfaces.

ProfileEducationFacet class

ProfileFacet

ProfileEducationElement class

ProfileEducationElement

 

Once the Facets and Elements are created, next step will be to register these Facets and Elements in Sitecore, we also call this deploying to Sitecore.

In order to deploy these facets and Elements, we can either update the default configuration file, or we can also create a patch file, which will have changes specific to Education Facets.

Here is the patch file for ref:

FacetDeployPatch

<configuration xmlns:patch=”http://www.sitecore.net/xmlconfig/”&gt;
<sitecore>
<model>
<elements>
<element patch:after=”*[@interface=’Sitecore.Analytics.Model.Entities.IBehaviorProfileValue, Sitecore.Analytics.Model’]” interface=”Sample._Classes.xDBProfile.Elements.IProfileEducationElement, Sample.Sitecore”
implementation=”Sample._Classes.xDBProfile.Elements.ProfileEducationElement, Sample.Sitecore” />
<element patch:after=”*[@interface=’Sitecore.Analytics.Model.Entities.IBehaviorProfileValue, Sitecore.Analytics.Model’]” interface=”Sample._Classes.xDBProfile.Facets.IProfileEducationFacet, Sample.Sitecore”
implementation=”Sample._Classes.xDBProfile.Facets.ProfileEducationFacet, Sample.Sitecore” />
</elements>
<entities>
<contact>
<facets>
<facet patch:after=”*[@name=’Preferences’]” name=”Education” contract=”Sample._Classes.xDBProfile.Facets.IProfileEducationFacet, Sample.Sitecore” />
</facets>
</contact>
</entities>
</model>
</sitecore>
</configuration>

Getting and setting properties are done using GetAttribute and SetAttribute methods retrieved from Sitecore.Analytics.Model.Framework.Element and Sitecore.Analytics.Model.Framework.Facet.

Happy learning 🙂

Sitecore MongoDB Blog series: Part 2-Understand scaling, contacts and queries

In previous blog post we have gone through MongoDB introduction with Sitecore, features and installation.In this blog we will go over available scaling options in MongoDB, and then followed with introduction to contacts and out of the box queries.

Scaling:

There are three types of scaling:

  1. Standalone environment
  2. Vertical Scaling and
  3. Horizontal Scaling

Standalone environment:

A standalone is all in one configuration, where we install all xDB components in the same computer, which includes:

  • Content management server
  • Content delivery server
  • Database server
  • Reporting server
  • Collection server.

This is not an optimal production environment setup, and it’s mostly resembles the development environment, where we have all components in the same workstation, we can say this setup as “not scalable environment”.

standalone-setup

Vertical Scaling:

Vertical scaling means adding more resources to single node in the system,which typically involves adding/upgrading more hardware to single machine.

When we start inclining towards Vertical setup, we tend to have separate servers for each component, i.e separate servers for:

  • Database
  • Content management
  • Content delivery and
  • Reporting server

If we see that specific component requires hardware upgrade, then we can just scale that environment/component up, without touching any other server, and this way we can scale the complete Sitecore system.

Horizontal Scaling:

Though we can scale each component of the System, by following vertical Scaling, but what about if we have just one Content delivery server and because of some server issue, we lost all data from that server, just can’t imagine right?

In this specific case even we have scaled up the content delivery server by upgrading the size,RAM and all other component(s) as per the requirements, but such thing can’t help us out if something goes wrong with that specific server, which will ultimately results in data loss.

In this scenario, we can resolve the issue by deploying multiple servers for the same components, which includes:

  • Multiple content management servers
  • Multiple content delivery servers
  • Multiple MongoDB(Analytics) servers
  • Separate session state server.

This type of setup helps in resolving the issue of, one server going down for some reason, From MongoDB presepective, we can achieve this by adding multiple servers for Analytics, we do it via adding Replica sets.

By means of replication we achieve following:

  • Availability
  • MongoDB provides high data availability with replica sets.
  • A replica set consists of two or more copies of the same data.

What happens in Replica set is, we setup the environment which defines a primary server, which will be used to read and write the Analytics  information, at the same time all data from replicaset-1 will get copied to replicaset-2 and replicaset-3, all the servers are always in sync.

From here, if something goes wrong to replicaset-1 server, MongoDB internally makes either replicaset-2 or replicaset-3 as a primary source of reading and writing the information, this we can always make sure data availability.

horizontal-scalibility

Introduction to Contacts:

  • In xDB a contact is an individual visitor.
  • This visitor may be anonymous or he may have been authenticated.
  • A contact is a combination of facets.
  • Contact Includes:
    • Identifiers
    • Personal Information
    • Email
    • Phone Number
    • Addresses

contacts

Identifying Contacts:

  • Contact identification is the process of connecting the current session, device and contact session to an identifier. This is implemented using the Identify() method which is part of the Sitecore Analytics tracker namespace.
  • Sitecore.Analytics.Tracker.Current.Session.Identify(identifier)
  • A contact is always identified by an identifier, identifier is an string value which uniquely identifies a contact in relation to website and this value is always provided by contact itself.
  • Identifiers can be one of the following:
    • User login
    • User id from third party system and/or
    • Email address

Here is the sample snippet which shows how we can validate the use in MongoDB:

mongo-validate-user

MongoDB Queries:

Let’s look into the sample two queries, which is used to fetch data from out of the collections.

Consider a case where we have millions of records in “Contacts” collection, and wants to get specific contact record, we can add a filter where we can pass “FirstName”, and we use “Personal.Firstname” Facet for this.

db.getCollection(‘Contacts’).find({“Personal.FirstName”:”Ankit Joshi”})

FirstNameFilter

Another example, if we want to find an identifier based on specific Id, we can use this query:

db.getCollection(‘Identifiers’).find({“_id”:”ANKIT”})

IdentifyFilter

In the same way we can also create custom collections, and add documents to it using Mongo Shell.

We can create custom collections using Mongo Shell, and the beauty of this is, when we try to create a new collection, and if that collection doesn’t exists it will create it automatically, and documents of the collections can have different structure, which makes it more flexible.

Let me know your feedback and comments if any?

References:

https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/xdb/platform/scalability_options

Happy learning 🙂

Sitecore MongoDB Blog series: Part 1-Introduction to MongoDB in Sitecore

Sitecore introduced MongoDB in it’s ecosystem to solve the problem of scaling analytics, let’s try to understand MongoDB from Sitecore prespective, and see how it’s useful and where exactly it sit in the Sitecore system, we will have series of three posts where we will start with the introduction about it, it’s features, advantages, setting up MongoDB in your environment.

In the second series we will talk about contacts and some of the out of the box queries, and will to understand MongoDB collection, and in the final post we will see how we can create custom facets to extend MongoDB functionality.

mongodb

Introduction to MongoDB

Sitecore 7.5 introduced MongoDB as the main datastore for the Sitecore Experience Database (xDB). Sitecore xDB allows organizations to collect all of their customer interactions from all channels to create a comprehensive, single view of the customer that allows marketers to better optimize the customer experience in real-time.

Following are some of the features of MongoDB:

  • Open source
  • NoSQL
  • Document oriented database.
  • Primarily used for collecting data and information about visitors(for analytics)
  • Visitors and their interactions are written to MongoDB in JSON format, which then processed by an aggregation pipeline into a format that is used for reporting.

There are several advantages and benefits with MongoDB, some of them are listed below:

  • Scalability
    • Standalone environment
    • Vertical Scaling and
    • Horizontal Scaling
  • Performance
  • Flexibility
  • Unstructured data and Schemas

Scaling is one of the critical feature in Sitecore, and we will discuss about all different scaling options in the next series of this post, where we will talk more about horizontal scaling and how MongoDB uses it to make sure the availability of data.

Installing MongoDB:

Let’s take a look, how you can install MongoDB:

Please follow the below steps, to install MongoDB.

  1. Download MongoDB as per your Sitecore version, you can see more details here: https://doc.sitecore.net/sitecore_experience_platform/setting_up_and_maintaining/xdb/platform/software_recommendations and
  2. https://kb.sitecore.net/articles/633863
  3. Next, you need to install Mongo, you can do it either in default installation path (C:\Program Files\MongoDB\Server\mongo version), or in custom path like (D:\Mongo\..)
  4. Create data and db folder:
    1. C:\Program Files\MongoDB\Server\3.0\data
    2. This folder is not created by default during installation, we need to install this.
    3. Once this folder is create, please create db folder under this.
  5. Create logs folder:
    1. C:\Program Files\MongoDB\Server\3.0\logs
  6. We can create a new config file where we specify db and logs folder, and this file will be used to install MongoDB as a service, so that it will start everytime when we start/boot windows.
  7. In this example, I have created a new folder “config” and added config file under that.
  8. C:\Program Files\MongoDB\Server\3.0\config
  9. Please use the below snippet and save make sure to change the db and log location, as per your environment location.mongoconfig
  10. C:\Program Files\MongoDB\Server\3.0\config\mongod-3.0.cfg
  11. Open up a Command Prompt (Run As Administrator), and navigate to bin folder
    1. C:\Program Files\MongoDB\Server\3.0\bin
  12. Run the following command to create MongoDB as a service:
  13. mongod –config=”C:\Program Files\MongoDB\Server\3.0\config\mongod-3.0.cfg” –install –serviceName=”MongoDB 3.0″
  14. Go to services and look for “MongoDB 3.0”, click startMongoDBService

Connection Strings:

mongo_connectionstring

  • name – analytics,tracking.live, tracking.history and tracking.contact.
  • mongodb prefix
  • servername- in case of local, it’s default to localhost
  • Mongo database(collection name)

Note:

This is for replicate set

mongo_connectionstring_replicaset

This is how contact looks in Mongo, and some out of the box properties.

contactcard

Hope this helps to give you base level understanding about MongoDB in Sitecore, and how to install MongoDB as windows service.

In the next post, we will see how we can scale MongoDB in Sitecore, and also closer look of contacts,collection and some queries to get data out of it.

Let me know your comments and feedback on the same, and anything which want to me cover specifically.

References:

https://briancaos.wordpress.com/2014/10/01/sitecore-and-xdb-setting-up-mongodb-on-your-developer-machine/

Happy learning 🙂