Querying Against ContentPart Fields

Topics: Writing modules
May 22, 2012 at 5:41 PM
Edited May 22, 2012 at 7:21 PM

The one item I am trying to figure out right now is a way to query against fields or utilize projections /queires via code.

I have a Part setup with two DateTime fields. I am now in need of querying the ContentManager for my part sorted by one of the DateTime fields, however I am somewhat at a loss on how to achieve this. 

Any suggestions?

 

Edit/Follow up: I suppose it may be possible by injecting a IProjectionManager as long as you had a Projection setup. Would this be a possible use-case for HqlQuery?

May 22, 2012 at 9:20 PM

You can retrieve all the fields of a part by 

var fields = part.Fields;
var dateTimeField = (DateTimeField)fields.Where(f => f.Name == "DateTime").FirstOrDefault();
There are probably errors with the code above. But that's how I would retrieve fields of a part.
Hope that help
May 22, 2012 at 9:46 PM

@minhtriho Thanks for the reply! However I am looking to do something more like...

_contentManager.Query(versionOptions, "ContentType").OrderBy(s => s.Fields.Where(f => f.Name =="DateTime") //Get storage etc.

From what I read however, this simply may not be possible. 

May 22, 2012 at 9:49 PM

I'm curious to see someone can make that work as well. It's good to see others having the same problem, that means I'm not crazy :D

Developer
May 22, 2012 at 10:20 PM

Fields are serialized and stored in the ContentItemVersionRecord table. Because of that querying on them is not possible. You could of course query the table through an IRepository to filter on the content of the Data column where fields are stored but that would be very ugly. If you really need querying you should user parts with records.

Coordinator
May 22, 2012 at 10:36 PM

Piedone is right, but not complete. Actually the Projector module will index any value from this XML to concrete table to make querying possible. Thus content items get a FieldIndexPart. Look at FieldIndexPartRecord to create your query.

Developer
May 22, 2012 at 10:43 PM

Now that's new for me, awesome!

Oct 30, 2012 at 9:10 PM
Edited Oct 30, 2012 at 9:12 PM

I also would like to search by field, or rather filter a list based on the values in the field, can you let me know if I am on the right track for using FieldIndexPartRecord to create my query?

First off...I don't see any way to do this query without adding a project ref to Orchard.Projections so that I can get access to the IRepository<FieldIndexPartRecord>.  Is this correct or is there a different/better way to accomplish the same thing without having to create the dependancy on Orchard.Projections in my own module?

I plan to use this repository to query the table based on the PropertyName and Value fields and then get the ContentItemRecord.Id property to populate a list of ids that I can then use to get only the content whose id in in that list.

I essentially want/need to be able to get a list of items that have a field with the selected value/filter.  In this specific case I would like to query a list of Work Orders whose Status (Drop Down List w/values Open,Closed,etc.) is "Open".

Ex:

var ids = _fieldIndexPartRepository.Fetch(
f => f.StringFieldIndexRecords.Any<StringFieldIndexRecord>(
r =>
r.PropertyName == "MyPart.MyPropertyName." &&
r.Value == "MyValue"
)
).Select(c => c.Id);
Coordinator
Oct 31, 2012 at 7:54 PM

Projections are the only part of Orchard that can query on field values currently. You'll have to either use projections or duplicate some of the code that's in there.

Jan 8, 2014 at 3:47 PM
Edited Jan 8, 2014 at 3:58 PM
Sorry, wrong discussion.