Sitecore.ContentSearch Search by Field Value - sitecore

How do I get a sitecore item in Sitecore 7.2 by its field (of type droptree) value using Sitecore.ContentSearch?
I've tried: context.GetQueryable<SearchResultItem>().FirstOrDefault(resultItem=>resultItem["Field Name"]=="{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}"); but no luck. Any tips?

Guids get indexed in a normalized format (lower case, no hyphens or braces). So if you want to search in this way, I think you need to normalize your search term.
See the 'slightly complex queries' section of this blog post:
http://www.xcentium.com/blog/2013/11/05/sitecore-7-linq-to-sitecore-simplified-part-1
By the way, if you do your query using a mapped POCO's rather than SearchResultItem then you can avoid having to manually do that normalization.

Try The following:
context.GetQueryable<SearchResultItem>().FirstOrDefault(resultItem=>resultItem["Field Name"]== Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid("{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}");
Or just like martin suggested, you can create your own POCO class which have a property of your field with type (Sitecore.Data.ID):
public class MyOwnPoco : SearchResultItem
{
public Sitecore.Data.ID MyField {get;set;}
}
context.GetQueryable<>().FirstOrDefault(i=> i.MyField == Sitecore.Data.ID.Parse("{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}"));

Related

Add properties to Google Datastore entity dynamically

I have a below use case:
I have a method that accepts a list of strings. For each of the strings, I need to create a property under an existing google data store entity A
Example: I have an existing entity Person with properties fname and lname.
If the input list has strings - address, city, I need to update the entity Person to include these new properties address and city.
I'm coding this use case in Python. Any suggestions on how I can achieve this?
So the best way to do this is to let your class inherit ndb.Expando. The difference between Expando and Model is that you can always add attributes to an Expando entity and be able to store it in the Datastore.
Knowing this, there are several ways to proceed, but I am guessing you’re also going to need to use Python’s setattr(object, name, value) method to pass the attribute name from a string.
Take a look at the Expando model class: https://cloud.google.com/appengine/docs/standard/python/ndb/creating-entity-models#creating_an_expando_model_class
class Person(ndb.Expando):
pass
person = Person(fname='some', lname='body')
person_key = person.put()
...
person = person_key.get()
person.city = 'San Francisco'
person.address = '1234 Main St.'
person.put()

Ordering Sitecore search results

I have a IQueryable<T> object as search results object.
I apply the filtering and sorting on this search object.
Before I call the GetResults(), I want to order the results based on one of the field's (Fieldname - Priority) value. So for all the items in the IQueryable<T> object, I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.
I have the fieldmap entry for Priority field.
search.OrderByDescending(i => !string.IsNullOrEmpty(i.GetItem().GetFieldValue("Priority")))
The above command doesn't work. Apparently, I can't use Sitecore extension methods with IQueryable?
If I convert search.ToList(). Do the ordering and then convert it back to AsQueryable(), I get the following error:
There is no method 'GetResults' on type 'Sitecore.ContentSearch.Linq.QueryableExtensions'
that matches the specified arguments
Is there a neat and quick way to get around this?
Cheers
I think you just need to add your field to your SearchResultItem and mark it as an int. I am making the assumption that the field is an int. Make a custom class that inherits SearchResultItem.
public class CustomSearchResultItem : SearchResultItem
{
[IndexField("Priority")]
public int Priority { get; set; }
}
Then use it in your search. Finally order by it.
using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var results = context.GetQueryable<CustomSearchResultItem>().Where(prod => prod.Content.Contains("search box text").OrderByDescending(t => t.Priority);
}
Some data found here.
http://www.sitecore.net/learn/blogs/technical-blogs/sitecore-7-development-team/posts/2013/10/sorting-and-ordering-results.aspx
You can order search results using multiple fields by using the OrderByDescending combined with ThenByDescending. So you would need to order by Priority and then by [Name|Date|Whatever].
I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.
I sort them first on the criteria chosen by the user - like Name, Date created etc. Once I get the results back, I need to order them by priority field
You are conflicting yourself in the questions and comments. If you want the results with priority first and then by user selected results then the following will work:
query = dataQuery.OrderByDescending(i => i.Title).ThenByDescending(i => i["Priority"]);
var results = query.GetResults().Hits.Select(h => h.Document);
There was a bug in earlier version of Sitecore which meant that the ThenBy clause will be added before the OrderBy clause hence it is added in reverse above. You may want to check if this is fixed in the current version. If so simply change your query to:
query = dataQuery.OrderByDescending(i => i["Priority"]).ThenByDescending(i => i.Title);
You don't have to add the field to your SearchResultItem if you just want to order by it, only if you need the actual value of that field returned to as well.
If you need to order by a custom user supplied value then you can pass in i => i["whatever-field-the-user-has-selected"] instead of i.Title.
You can find more info in this blog post.

Sitecore/Glass Mapper: how to return query in order of content tree

We have a site with several queries that query the direct children of a content item. We simply want just the children sorted by the order they appear in the content tree.
We're using Glass Mapper and our collection properties look like this:
[SitecoreQuery("/sitecore/content/Global/Team Members/Categories/*")]
public IEnumerable<ICategory> Categories { get; set; }
The above property Categories returns the child items in what seems to be alpha order, but in some cases it seems a bit random.
Any idea how to set up the query to pull in the order of the content tree?
Scott,
I believe that Glass is using fast query for these SitecoreQueries which is why you aren't getting any predictable sort order. Unfortunately the fast query does not allow sorting in the query syntax. You will see the same if you put your query into the XPath Builder in Sitecore's Developer Center by using this syntax:
fast:/sitecore/content/Global/Team Members/Categories/*
I think the quickest way to resolve this is to just add Sitecore's __Sortorder field to your ICategory definition.
[SitecoreField("__Sortorder"),]
string Sortorder { get; set; }
You could then add another property to your model that returns the sorted version of this.
public IEnumberable<ICategory> SortedCategories { get { return Categories.OrderBy(s=>s.Sortorder); } }
Keep in mind you can also use the [SitecoreChildren] decorator to get the children of the current item. I'm not sure if that is actually what you are after, but that decorator will actually return your items in the correct order per Sitecore's SortOrder.

Sitecore 7 ContentSearch API with numeric POCO properties in the filter / where condition not working

I have been spending few hours on this issue now, but no luck so far. So reaching out to the community for help.
I have a data template called Product with a field called ProPrice, and some content based on this template I have enabled all fields to be indexed using the configuration <indexAllFields>true</indexAllFields>. When I rebuild the index, I see the index field (proprice) along with the terms stored in Lucene correctly (verified using Luke).
Now I use Sitecore 7 ContentSearch API to fetch content from Lucene index. And for this, I have created a POCO entity called Product, which inherits from SearchResultItem, and have also added a property for price as below:
[IndexField("proprice")]
public double Price { get; set; }
However the following LINQ query does not return any data:
var products = context.GetQueryable<Product>().Where(p => p.Price == 4.0).ToList();
When I look at Sitecore search log, the Lucene query that this translated to was - proprice:[4 TO 4]. And if I execute this query directly against the index in Luke, it returns data. I tried this with other conditions such as p.Price >= 1.0, but none worked. What is interesting is - when I remove the condition and get all records, the Price property in the Product entity is populated with the correct double value (4.0).
But if I change the query slightly as follows, it returns correct data:
var products = context.GetQueryable<Product>().Where(p => p["proprice"] == "4").ToList();
So it looks like when the condition is against numeric values, it does not work. And unfortunately, I need to filter based on a numeric range, and hence the above approach will not work for me. I can avoid ContentSearch API and directly execute the Lucene query using the Lucene provider, but I will not be able to switch to a different search provider, such as Solr, in future. Or alternatively, I can get all data, and then filter in my code - I wouldn't prefer that though.
I would appreciate any help in resolving this.
PS: Few other points:
1) I tried the field type of "ProPrice" in the data template as single line text, integer, double - none worked
2) Am using the default Lucene analyzer - Lucene.Net.Analysis.Standard.StandardAnalyzer
You need to map your index field type to system.double as follows (Notice type="System.Double"):
<field fieldName="proprice" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" type="System.Double" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider">
<analyzer type="[YOUR ANALYZER]" />
</field>
I think you need the type converter attribute adding to the field. I've done this in my projects and filtering on numbers has worked fine:
So change the property to:
[IndexField("proprice")]
[TypeConverter(typeof(IndexFieldNumberValueConverter))]
public double Price { get; set; }
And you should be able to filter.

How to get field name

Recently i have implemented django-sphinx search on my website.
It is working fine of each separate model.
But now my client requirement has changed.
To implement that functionality i need field name to whom search is made.
suppose my query is:
"select id, name,description from table1"
and search keyword is matched with value in field "name". So i need to return that field also.
Is it possible to get field name or any method provided by django-sphinx which return field name.
Please help me...
As far as I know, this isn't possible. You might look at the contents of _sphinx though.
Well from django-sphinx it might not be possible. But there is a solution -
Make different indexes, each index specifying the field that you need to search.
In your django-sphinx models while searching do this -
search1 = SphinxSearch(index='index1')
search2 = SphinxSearch(index='index2')
...
After getting all the search results, you aggregate them & you have the info of from where they have come.