Early Bird Registration for DrupalCon Portland 2024 is open! Register by 23:59 PST on 31 March 2024, to get $100 off your ticket.
I am trying to use search API with the REST API provided with services. I have a view(as described below), a search index which indexes nodes, and a service endpoint. When i use the browser to directly access the view, the results are correct, but when I send a get request to the rest endpoint, I get something like
[
{
"price": null,
"description": null,
"title": "",
"image_url": "",
"company": "",
"hot_deal": null,
"nid": "0",
"name": "",
"uid": "0",
"html": null
}
]
The view:
$view = new view();
$view->name = 'search_products';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'search_api_index_products';
$view->human_name = 'Search Products';
$view->core = 7;
$view->pi_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'none';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* No results behavior: Global: Result summary */
$handler->display->display_options['empty']['result']['id'] = 'result';
$handler->display->display_options['empty']['result']['table'] = 'views';
$handler->display->display_options['empty']['result']['field'] = 'result';
$handler->display->display_options['empty']['result']['empty'] = TRUE;
/* Relationship: Indexed Node: Author */
$handler->display->display_options['relationships']['author']['id'] = 'author';
$handler->display->display_options['relationships']['author']['table'] = 'search_api_index_products';
$handler->display->display_options['relationships']['author']['field'] = 'author';
/* Relationship: Indexed Node: Image » The image file. */
$handler->display->display_options['relationships']['field_image_file']['id'] = 'field_image_file';
$handler->display->display_options['relationships']['field_image_file']['table'] = 'search_api_index_products';
$handler->display->display_options['relationships']['field_image_file']['field'] = 'field_image_file';
/* Relationship: User: Exhibitor profile */
$handler->display->display_options['relationships']['profile_exhibitor']['id'] = 'profile_exhibitor';
$handler->display->display_options['relationships']['profile_exhibitor']['table'] = 'entity_user';
$handler->display->display_options['relationships']['profile_exhibitor']['field'] = 'profile_exhibitor';
$handler->display->display_options['relationships']['profile_exhibitor']['relationship'] = 'author';
/* Field: Indexed Node: Price */
$handler->display->display_options['fields']['field_price']['id'] = 'field_price';
$handler->display->display_options['fields']['field_price']['table'] = 'search_api_index_products';
$handler->display->display_options['fields']['field_price']['field'] = 'field_price';
$handler->display->display_options['fields']['field_price']['label'] = 'price';
$handler->display->display_options['fields']['field_price']['settings'] = array(
'thousand_separator' => '',
'prefix_suffix' => 1,
);
/* Field: Indexed Node: The main body text */
$handler->display->display_options['fields']['body']['id'] = 'body';
$handler->display->display_options['fields']['body']['table'] = 'search_api_index_products';
$handler->display->display_options['fields']['body']['field'] = 'body';
$handler->display->display_options['fields']['body']['label'] = 'description';
$handler->display->display_options['fields']['body']['type'] = 'text_plain';
/* Field: Indexed Node: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'search_api_index_products';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = 'title';
$handler->display->display_options['fields']['title']['link_to_entity'] = 0;
/* Field: File: URL */
$handler->display->display_options['fields']['url']['id'] = 'url';
$handler->display->display_options['fields']['url']['table'] = 'entity_file';
$handler->display->display_options['fields']['url']['field'] = 'url';
$handler->display->display_options['fields']['url']['relationship'] = 'field_image_file';
$handler->display->display_options['fields']['url']['label'] = 'image_url';
$handler->display->display_options['fields']['url']['link_to_entity'] = 0;
/* Field: Profile: Company » Company */
$handler->display->display_options['fields']['field_profile_organisation_name']['id'] = 'field_profile_organisation_name';
$handler->display->display_options['fields']['field_profile_organisation_name']['table'] = 'entity_profile2';
$handler->display->display_options['fields']['field_profile_organisation_name']['field'] = 'field_profile_organisation_name';
$handler->display->display_options['fields']['field_profile_organisation_name']['relationship'] = 'profile_exhibitor';
$handler->display->display_options['fields']['field_profile_organisation_name']['label'] = 'company';
$handler->display->display_options['fields']['field_profile_organisation_name']['link_to_entity'] = 0;
/* Field: Indexed Node: Hot Deal */
$handler->display->display_options['fields']['field_hot_deal']['id'] = 'field_hot_deal';
$handler->display->display_options['fields']['field_hot_deal']['table'] = 'search_api_index_products';
$handler->display->display_options['fields']['field_hot_deal']['field'] = 'field_hot_deal';
$handler->display->display_options['fields']['field_hot_deal']['label'] = 'hot_deal';
/* Field: Indexed Node: Node ID */
$handler->display->display_options['fields']['nid_1']['id'] = 'nid_1';
$handler->display->display_options['fields']['nid_1']['table'] = 'search_api_index_products';
$handler->display->display_options['fields']['nid_1']['field'] = 'nid';
$handler->display->display_options['fields']['nid_1']['label'] = 'nid';
$handler->display->display_options['fields']['nid_1']['separator'] = '';
$handler->display->display_options['fields']['nid_1']['link_to_entity'] = 0;
/* Field: User: Name */
$handler->display->display_options['fields']['name']['id'] = 'name';
$handler->display->display_options['fields']['name']['table'] = 'entity_user';
$handler->display->display_options['fields']['name']['field'] = 'name';
$handler->display->display_options['fields']['name']['relationship'] = 'author';
/* Field: User: User ID */
$handler->display->display_options['fields']['uid']['id'] = 'uid';
$handler->display->display_options['fields']['uid']['table'] = 'entity_user';
$handler->display->display_options['fields']['uid']['field'] = 'uid';
$handler->display->display_options['fields']['uid']['relationship'] = 'author';
$handler->display->display_options['fields']['uid']['label'] = 'uid';
$handler->display->display_options['fields']['uid']['separator'] = '';
$handler->display->display_options['fields']['uid']['link_to_entity'] = 0;
/* Field: Indexed Node: The main body text */
$handler->display->display_options['fields']['body_1']['id'] = 'body_1';
$handler->display->display_options['fields']['body_1']['table'] = 'search_api_index_products';
$handler->display->display_options['fields']['body_1']['field'] = 'body';
$handler->display->display_options['fields']['body_1']['label'] = 'html';
$handler->display->display_options['filter_groups']['groups'] = array(
1 => 'AND',
2 => 'AND',
);
/* Filter criterion: Indexed Node: Price */
$handler->display->display_options['filters']['field_price']['id'] = 'field_price';
$handler->display->display_options['filters']['field_price']['table'] = 'search_api_index_products';
$handler->display->display_options['filters']['field_price']['field'] = 'field_price';
$handler->display->display_options['filters']['field_price']['operator'] = '>=';
$handler->display->display_options['filters']['field_price']['group'] = 1;
$handler->display->display_options['filters']['field_price']['exposed'] = TRUE;
$handler->display->display_options['filters']['field_price']['expose']['operator_id'] = 'field_price_op';
$handler->display->display_options['filters']['field_price']['expose']['label'] = 'price_smaller';
$handler->display->display_options['filters']['field_price']['expose']['operator'] = 'field_price_op';
$handler->display->display_options['filters']['field_price']['expose']['identifier'] = 'field_price';
$handler->display->display_options['filters']['field_price']['expose']['remember_roles'] = array(
2 => '2',
1 => 0,
3 => 0,
6 => 0,
4 => 0,
7 => 0,
5 => 0,
8 => 0,
);
$handler->display->display_options['filters']['field_price']['group_info']['label'] = 'Price';
$handler->display->display_options['filters']['field_price']['group_info']['identifier'] = 'field_price';
$handler->display->display_options['filters']['field_price']['group_info']['remember'] = FALSE;
$handler->display->display_options['filters']['field_price']['group_info']['group_items'] = array(
1 => array(),
2 => array(),
3 => array(),
);
/* Filter criterion: Indexed Node: Price */
$handler->display->display_options['filters']['field_price_1']['id'] = 'field_price_1';
$handler->display->display_options['filters']['field_price_1']['table'] = 'search_api_index_products';
$handler->display->display_options['filters']['field_price_1']['field'] = 'field_price';
$handler->display->display_options['filters']['field_price_1']['operator'] = '<=';
$handler->display->display_options['filters']['field_price_1']['group'] = 1;
$handler->display->display_options['filters']['field_price_1']['exposed'] = TRUE;
$handler->display->display_options['filters']['field_price_1']['expose']['operator_id'] = 'field_price_1_op';
$handler->display->display_options['filters']['field_price_1']['expose']['label'] = 'price_larger';
$handler->display->display_options['filters']['field_price_1']['expose']['operator'] = 'field_price_1_op';
$handler->display->display_options['filters']['field_price_1']['expose']['identifier'] = 'field_price_1';
$handler->display->display_options['filters']['field_price_1']['expose']['remember_roles'] = array(
2 => '2',
1 => 0,
3 => 0,
6 => 0,
4 => 0,
7 => 0,
5 => 0,
8 => 0,
);
/* Filter criterion: Indexed Node: Title */
$handler->display->display_options['filters']['title']['id'] = 'title';
$handler->display->display_options['filters']['title']['table'] = 'search_api_index_products';
$handler->display->display_options['filters']['title']['field'] = 'title';
$handler->display->display_options['filters']['title']['group'] = 2;
$handler->display->display_options['filters']['title']['exposed'] = TRUE;
$handler->display->display_options['filters']['title']['expose']['operator_id'] = 'title_op';
$handler->display->display_options['filters']['title']['expose']['label'] = 'name';
$handler->display->display_options['filters']['title']['expose']['operator'] = 'title_op';
$handler->display->display_options['filters']['title']['expose']['identifier'] = 'title';
$handler->display->display_options['filters']['title']['expose']['remember_roles'] = array(
2 => '2',
1 => 0,
3 => 0,
6 => 0,
4 => 0,
7 => 0,
5 => 0,
8 => 0,
);
/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page_1');
$handler->display->display_options['defaults']['hide_admin_links'] = FALSE;
$handler->display->display_options['path'] = 'psearch';
Comments
Comment #1
Dippers CreditAttribution: Dippers commentedThis fails because search_api views uses entity views. However the simple rendering employed by Services Views doesn't render entity views fields. In particular entity view fields need to be pre_rendered before they are displayed as it is the pre_render that wrappers the entity and attaches it to the view.
I have attached a patch for this but I haven't tried it out on all possible use cases. It works fine for entity views but it might break standard views. The patch also normalises the differences between rendering in views preview and in service output as I preferred them to be exactly the same.
Comment #2
Dippers CreditAttribution: Dippers commentedThis is a slightly more aggressive patch in that it themes every field even if the raw data is available in the results. This ensures any rewrite/link post processing is also done on all fields.
Comment #3
frankyn CreditAttribution: frankyn commentedHi,
Awesome work on the patch you made. I applied it and got a few funny results. I'm attaching the before/after json structures that are being printed out.
If there is anything I can do to help, please let me know.
Again awesome work and thanks a lot!
Frank N.
Comment #4
Dippers CreditAttribution: Dippers commentedWhat is the expected output? I would need to see the exported view to see what rewrite rules you have in place. Which endpoint are you using, direct from the views service or from the generic /views/{view_id}?display_id={display_id} ?
Comment #5
matthandI'm working with Frankyn and he's using a custom path in services views that is used as a new service resource. He's not calling the endpoint with the views resource. It's more like {domain}/{rest_server}/notifications.json
And the main issue we see is that a Global Custom Text field with a token rewrite is working great. BUT, the value is somehow included as the Message ID as well. You can see it in his printout. The message_users_mid field should equal an integer (1, 2, 3, etc) but it's instead equaling a token form the Global Custom Text field below it called "unknown". And, the label doesn't show as the field name for the custom text field. It always shows as "unknown" despite what is entered as a label.
Thank you for the patch. It's a huge improvement over the original formatting of Services Views. Frankyn will be available late today and he'll provide a views export for you to look at. He's also here to help code and squash bugs if you need it.
Comment #6
frankyn CreditAttribution: frankyn commentedI added an export for the view definitions below:
Comment #7
Dippers CreditAttribution: Dippers commentedYour view is working as expected.
Labels for service view fields must only include lower case and underscores. Change your global text field label to 'custom' and it will work whereas 'Custom Text' which is the default will not.
Your view doesn't actually have the message id field included. The message id label is actually on the content field. If you change your labels to actually indicate the field they are on you will see what I mean. I'm not sure what the rendered message field should be giving.
Here is the view with labels set and the message id field added:
Comment #8
frankyn CreditAttribution: frankyn commentedThanks a lot for the help!
I tried out what you said and it gave back correct key values.
Why do capital, spaced, titles not work?
Frank N.
Comment #9
frankyn CreditAttribution: frankyn commentedI added the following to the code, to clean it up a little bit. I figure how it's still a view you're not required to make caption specific. I forced the caption to fit the requirement instead.
Comment #10
frankyn CreditAttribution: frankyn commentedHere is your 2b patch + my changes as a patch.
Thanks!
Comment #11
Dippers CreditAttribution: Dippers commentedYou are using $field->options['label'] before checking whether it exists or not.
Comment #12
frankyn CreditAttribution: frankyn commentedYes! You are right I misplaced the preg_replace().
Attached is an updated version.
Thanks for the feedback.
Frank N.
Comment #13
frankyn CreditAttribution: frankyn commentedHi Dippers,
I was wondering if it would be okay to message you, I'd like to talk a little bit about something I had questions about.
Frank N.
Comment #14
frankyn CreditAttribution: frankyn commentedI added additional functionality to your 2b patch but also removed the pre_replace and match because I wanted to allow capitals and spacing inside key's.
The additional functionality is for strip_tags ( ) option inside views. It was operational on the output from services_views. I added in the attached patch.
Frank N.
Comment #15
Jaesin CreditAttribution: Jaesin commentedIs there any support planned for multi-value text fields or multi-value term references?
Comment #16
Dippers CreditAttribution: Dippers commentedThis is someway off the original topic but multi-value fields should work. I have multi value term references working using a simple separator.
Comment #17
ianmen CreditAttribution: ianmen commentedQuick question: is there also a patch available for Drupal 6 ?
Comment #18
cybertoast CreditAttribution: cybertoast commentedOne addition to this. It seems like there's a limitation in that the services_views is honoring the patch only partially. The view is rendered to take the Rewrite Results into consideration thanks to the patch, but then the Raw vs Rendered handler just subsequent to the view renderer overwrites the values.
The solution, I think, is to replace the following in sevices_views.resource.inc
I'm not sure this is correct, but the behavior seems consistent with the services_views_retrieve() function's implementation. Could someone please correct me if my logic is wrong, or if this is not the appropriate drupal-ish way to do this.
Also, I'm happy to provide a patch once I get any feedback.
Thanks
Update: I've been adding my code into https://github.com/cybertoast/services_views if anyone finds that more convenient. See the branches for specific implementations.
Comment #19
pippopeppe CreditAttribution: pippopeppe commentedthe patch #14 works perfectly for me.
Thanks!
Comment #20
Exploratus CreditAttribution: Exploratus commentedWhen I tried to use "Rewrite the output of this field" in views I was getting to output, that was fixed with patch in #14. Thanks! Now I can see the output when using "Rewrite the output of this field".
For reference: https://drupal.org/node/1881112
Comment #21
Dubs CreditAttribution: Dubs commentedThanks for this patch - works well for me.
Comment #22
ajlow CreditAttribution: ajlow commentedThis patches works for me. Thank you!
One thing I did notice though is that all my empty fields are being placed at the end of the JSON array rather than in the field order I specified in the view.
Is there a way to ensure the order set in the view is kept rather than showing all empty fields at the end?
Actually, should I be concerned with the order of the fields in the JSON array?
Comment #23
yaworsk CreditAttribution: yaworsk commentedGreat patch. So far so good, will report back any problems encountered. Thanks for sharingthe solution.
Comment #24
yaworsk CreditAttribution: yaworsk commentedSorry, also, don't think this is a feature so much as a bug since the module doesn't entirely replicate views execution, right?
Comment #25
eojthebraveThis works for me too. Here's a version of the patch that follows the Drupal coding standards as well as removing lines of code rather then just commenting them out. Thanks!
Comment #26
dmsmidtNice patch (#25)!
Works for me on first glance.
Will report back if I find something strange.
Comment #27
michaelmallett CreditAttribution: michaelmallett commentedThis gives me a lot of Warnings, adds hundred per call.
Warning: Cannot use a scalar value as an array in drupal_render() (line 5930 of /Users/MIchael/Sites/zsl/docroot/includes/common.inc).
Warning: Cannot use a scalar value as an array in drupal_render() (line 5985 of /Users/MIchael/Sites/zsl/docroot/includes/common.inc).
Warning: Invalid argument supplied for foreach() in element_children() (line 6465 of
Warning: strip_tags() expects parameter 1 to be string, array given in services_views_execute_view()
Notice: Undefined offset: 0 in services_views_execute_view() (line 219 of etc...services_views.resource.inc)
this is all a bit above my head tbh, I've tried going through the patch but got a little lost
Comment #28
edmargomes CreditAttribution: edmargomes commentedHi, it doesn't work for me using solr. I need remove this line:
because the properties doesn't exist in $item. This line wasn't in the patch #14.
Comment #29
florisg CreditAttribution: florisg commentedupdated #28 against latest 7.x-1.x-dev from git (2013-Oct-01)
thanks for sorting this out :)
Comment #30
natuk#25 for
services_views.resource.inc
and #29 forviews_plugin_display_services.inc
work for me as well.Comment #31
sergiu.savva CreditAttribution: sergiu.savva commented#29 works for me, thanks ;)
Comment #32
davemybes CreditAttribution: davemybes commentedI concur: #25 for services_views.resource.inc and #29 for views_plugin_display_services.inc work for me as well. I now see the url alias being output correctly.
Comment #33
kylebrowning CreditAttribution: kylebrowning commentedThis needs to be re-rolled once again.
Comment #34
michaelmallett CreditAttribution: michaelmallett commentedAm I the only person that gets those warnings, or is everyone else ignoring/suppressing them? I literally get thousands per call and it renders my logs pretty useless.
Comment #35
b_sharpe CreditAttribution: b_sharpe commentedmichaelmallett, are you by chance using a reverse relationship (Content entity that is referencing Content via )?
I also am getting just spammed in the logs and as soon as I remove the relationship it works, but yet a page view of the same settings works...
Comment #36
nikunjkotechacombined #25 and #29 and modified a bit to get it working for version 7.x-1.1
Comment #37
nikunjkotechaupdated patch file in #36 to exclude local directories and verified it's working for new drupal install
Comment #38
nikunjkotechaComment #39
d70rr3s CreditAttribution: d70rr3s as a volunteer commentedHello, I'm don't if is worthy but in my case only works the patch #14 and also I was getting an array of empty stdClasses. I'm with the version 1.1 of Services module
Comment #40
rcodina CreditAttribution: rcodina commentedPatch on #37 works for me with Services 3.13 and Services Views 1.1
Comment #41
nikunjkotechaComment #42
jannis CreditAttribution: jannis commented#37 worked like a charm for me
Comment #43
jannis CreditAttribution: jannis commented#37 worked like a charm for me
Comment #44
adolfo.mansilla CreditAttribution: adolfo.mansilla commented#37 worked like a charm for me
Comment #45
priyanka12chavan CreditAttribution: priyanka12chavan commented#37 Worked for me. Thanks Nikunj!!
Comment #46
kylebrowning CreditAttribution: kylebrowning commentedComment #49
lily.yan CreditAttribution: lily.yan commentedAbout the change in this issue, it strips the tags which aren't allowed to remove all values of location API and service views for location API field is giving NULL values. This fix is under #2907068: Services Views for location field is giving NULL values.