<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>entity field query | 伪架构师</title>
    <link>/tags/entity-field-query/</link>
      <atom:link href="/tags/entity-field-query/index.xml" rel="self" type="application/rss+xml" />
    <description>entity field query</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Wed, 06 Apr 2016 16:44:01 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>entity field query</title>
      <link>/tags/entity-field-query/</link>
    </image>
    
    <item>
      <title>如何使用EntityFieldQuery</title>
      <link>/post/drupal-entityfieldquery-guide/</link>
      <pubDate>Wed, 06 Apr 2016 16:44:01 +0800</pubDate>
      <guid>/post/drupal-entityfieldquery-guide/</guid>
      <description>

&lt;p&gt;如何使用 EntityFieldQuery&lt;/p&gt;

&lt;p&gt;EntityFieldQuery 是 Drupal 7 中新增的一个类，允许利用指定条件获取符合条件的实体。查询条件可以基于属性，字段值以及一些其他的通用的实体元数据。他的语法非常紧凑和实用，而且这一功能由Drupal核心提供，无需另外安装其他模块。&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes--entity.inc/class/EntityFieldQuery/7&#34; target=&#34;_blank&#34;&gt;API 手册&lt;/a&gt;以及 modules\simpletest\tests\entity_query.test 中的测试用例，可以作为 EntityFieldQuery 的权威文档。&amp;rdquo;EntityFieldQuery&amp;rdquo; 类包含于 includes/entity.inc中。本文仅作为一个入门的简介供读者参考。&lt;/p&gt;

&lt;h2 id=&#34;建立一个查询&#34;&gt;建立一个查询&lt;/h2&gt;

&lt;p&gt;下面是一个简单的查询，用来查询所有包含今年教员照片的所有文章。下面的最后五行代码，&lt;code&gt;$result&lt;/code&gt;是一个联合数组，第一个键是实体类型，第二个键是实体编号（例如&lt;code&gt;$result[&#39;node&#39;][12322] = Node数据&lt;/code&gt; ），注意如果结果集为空，则其中不会有 &amp;lsquo;node&amp;rsquo; 键，因此需要用 isset来检查，&lt;a href=&#34;http://drupal.org/node/1427098&#34; target=&#34;_blank&#34;&gt;这里&lt;/a&gt;介绍了这种做法的来由。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php
$query = new EntityFieldQuery();
$query-&amp;gt;entityCondition(&#39;entity_type&#39;, &#39;node&#39;)
-&amp;gt;entityCondition(&#39;bundle&#39;, &#39;article&#39;)
-&amp;gt;propertyCondition(&#39;status&#39;, 1)
-&amp;gt;fieldCondition(&#39;field_news_types&#39;, &#39;value&#39;, &#39;spotlight&#39;, &#39;=&#39;)
-&amp;gt;fieldCondition(&#39;field_photo&#39;, &#39;fid&#39;, &#39;NULL&#39;, &#39;!=&#39;)
-&amp;gt;fieldCondition(&#39;field_faculty_tag&#39;, &#39;tid&#39;, $value)
-&amp;gt;fieldCondition(&#39;field_news_publishdate&#39;, &#39;value&#39;, $year . &#39;%&#39;, &#39;like&#39;)
-&amp;gt;fieldOrderBy(&#39;field_photo&#39;, &#39;fid&#39;, &#39;DESC&#39;)
-&amp;gt;range(0, 10)
-&amp;gt;addMetaData(&#39;account&#39;, user_load(1)); // Run the query as user 1.
$result = $query-&amp;gt;execute();
if (isset($result[&#39;node&#39;])) {
$news_items_nids = array_keys($result[&#39;node&#39;]);
$news_items = entity_load(&#39;node&#39;, $news_items_nids);
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;entitycondition-name-value-operator-null-http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3aentitycondition-7&#34;&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes--entity.inc/function/EntityFieldQuery%3A%3AentityCondition/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;-&amp;gt;entityCondition($name, $value, $operator = NULL)&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;entityConditions 是绝大多数实体类在 DrupalDefaultEntityController 类都应该支持的查询条件。&lt;/p&gt;

&lt;h3 id=&#34;entity-type&#34;&gt;entity_type&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;取值举例：&amp;rsquo;node&amp;rsquo;, &amp;lsquo;taxnonomy_term&amp;rsquo;, &amp;lsquo;comment&amp;rsquo;, &amp;lsquo;user&amp;rsquo;, &amp;lsquo;file&amp;rsquo;&lt;/li&gt;
&lt;li&gt;操作符举例：不需要&lt;/li&gt;
&lt;li&gt;$query-&amp;gt;entityCondition(&amp;lsquo;entity_type&amp;rsquo;, &amp;lsquo;node&amp;rsquo;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;bundle-comment实体类型不支持&#34;&gt;bundle（comment实体类型不支持）&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;取值举例：&amp;rsquo;artical&amp;rsquo;, &amp;lsquo;page&amp;rsquo;&lt;/li&gt;
&lt;li&gt;操作符举例：&amp;rsquo;=&amp;rsquo; 字符串，或者 &amp;lsquo;IN&amp;rsquo; 数组&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$query-&amp;gt;entityCondition(&#39;bundle&#39;, &#39;article&#39;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;revision-id&#34;&gt;revision_id&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;取值举例：3, 4, 52, 342&lt;/li&gt;
&lt;li&gt;操作符举例：整数&lt;code&gt;=, &amp;lt;, &amp;gt;, !=&lt;/code&gt;，数组可以使用&amp;rsquo;IN&amp;rsquo;和&amp;rsquo;NOT IN&amp;rsquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$query-&amp;gt;entityCondition(&#39;revision_id&#39;, $revision_id, &#39;=&#39;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;entity-id-例如-node-id&#34;&gt;entity_id 例如 node id&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;取值举例：3,4,52,342&lt;/li&gt;
&lt;li&gt;操作符举例：整数 &lt;code&gt;=, &amp;lt;, &amp;gt;, !=&lt;/code&gt;，数组可以使用 &amp;lsquo;IN&amp;rsquo; 和 &amp;lsquo;NOT IN&amp;rsquo;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$query-&amp;gt;entityCondition(&#39;entity_id&#39;, array(17, 21,422), &#39;IN&#39;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;propertycondition-name-value-operator-null-http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3apropertycondition-7&#34;&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3ApropertyCondition/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;-&amp;gt;propertyCondition($name, $value, $operator = NULL)&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;这些条件针对各种实体实现，例如Node, user, comment等。基本上是映射到entity自身的数据表字段中。例如node, users, comment, &lt;code&gt;file_managed&lt;/code&gt;, &lt;code&gt;taxonomy_term_data&lt;/code&gt;类似的表。用grep/search来查找&amp;rdquo;Implements hook_entity_info()&amp;ldquo;能查到实体对应的数据表。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;status (nodes)&lt;/strong&gt; 例如： &lt;code&gt;-&amp;gt;propertyCondition(&#39;status&#39;, 1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;type (nodes)&lt;/strong&gt; 例如： &lt;code&gt;-&amp;gt;propertyCondition(&#39;type&#39;, array(&#39;article&#39;, &#39;page&#39;, &#39;blog&#39;))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uid (nodes)&lt;/strong&gt; 例如： &lt;code&gt;-&amp;gt;propertyCondition(&#39;uid&#39;, $uid)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uri (media)&lt;/strong&gt; 例如： &lt;code&gt;-&amp;gt;propertyCondition(&#39;uri&#39;, &#39;%.jpg&#39;, &#39;LIKE&#39;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;type (media)&lt;/strong&gt; 例如： &lt;code&gt;-&amp;gt;propertyCondition(&#39;type&#39;, &#39;image&#39;);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;##&lt;a href=&#34;http://api.drupal.org/api/drupal/includes--entity.inc/function/EntityFieldQuery%3A%3AfieldCondition/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;-&amp;gt;fieldCondition($field, $column = NULL, $value = NULL, $operator = NULL, $delta_group = NULL, $language_group = NULL)&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这类条件针对实体的字段来执行。&lt;/p&gt;

&lt;p&gt;比如要查找 article node 的 body 字段：&lt;code&gt;-&amp;gt;fieldCondition(&#39;body&#39;, &#39;value&#39;, &#39;A&#39;, &#39;STARTS_WITH&#39;)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;字段名称：一般来说，一个表如果叫 &lt;code&gt;field_data_body&lt;/code&gt;，实际的字段名就是 body。这个配置保存在 &lt;code&gt;field_config_instance&lt;/code&gt; 表中。&lt;/li&gt;
&lt;li&gt;列：这是在数据库中对应的列的列名称去掉前缀的部分。body字段的数据库列为 &lt;code&gt;body_value&lt;/code&gt;, &lt;code&gt;body_summary&lt;/code&gt;, &lt;code&gt;body_format&lt;/code&gt;以及 language。真正使用时会使用 value, summary, format 以及 language。
类似的，image 字段会使用 fid, alt 以及 title 作为列名；entity 引用字段会使用&lt;code&gt;target_id&lt;/code&gt;以及&lt;code&gt;target_type&lt;/code&gt;作为列名。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;propertyorderby-column-direction-asc-http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3apropertyorderby-7&#34;&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes--entity.inc/function/EntityFieldQuery%3A%3ApropertyOrderBy/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;-&amp;gt;propertyOrderBy($column, $direction = &#39;ASC&#39;)&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;不是对所有属性都生效的。&lt;/p&gt;

&lt;h2 id=&#34;http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3arange-7-http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3arange-7&#34;&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3Arange/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;http://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3Arange/7&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;限制查询结果集的范围。&lt;/p&gt;

&lt;h2 id=&#34;count-http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3acount-7&#34;&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3Acount/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;-&amp;gt;count()&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;设置查询只返回数量，例如：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;$count = $query-&amp;gt;count()-&amp;gt;execute();
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;addmetadata-key-object-http-api-drupal-org-api-drupal-includes-entity-inc-function-entityfieldquery-3a-3aaddmetadata-7&#34;&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes!entity.inc/function/EntityFieldQuery%3A%3AaddMetaData/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;-&amp;gt;addMetaData($key, $object)&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;在查询中加入其他元数据。因为 EntityFieldQuery 的 fieldCondition 会使用当前用户的权限进行查询，这通常不是我们想要的结果，所以这个方法的一个重要的用途就是用其他用户的身份进行查询，可以在这里使用1号用户进行查询：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;$query-&amp;gt;addMetaData(&#39;account&#39;, user_load(1));
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;随机排序&#34;&gt;随机排序&lt;/h2&gt;

&lt;p&gt;最简单的随机排序方法就是添加一个 tag，然后进行一次 alter。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php
function mymodule_superblock() {
  $query = new EntityFieldQuery();
  $result = $query
    -&amp;gt;entityCondition(&#39;entity_type&#39;, &#39;node&#39;)
    -&amp;gt;fieldCondition(&#39;field_categories&#39;, &#39;tid&#39;, array(&#39;12&#39;,&#39;13&#39;), &#39;IN&#39;)
    -&amp;gt;propertyCondition(&#39;status&#39;, 1)
    -&amp;gt;addTag(&#39;random&#39;)
    -&amp;gt;range(0,5)
    -&amp;gt;execute();
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来做 alter&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php
function mymodule_query_random_alter($query){
  $query-&amp;gt;orderRandom();
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;参考：&lt;a href=&#34;http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_query_TAG_alter/7&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;hook_query_TAG_alter&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;排错&#34;&gt;排错&lt;/h2&gt;

&lt;p&gt;根据在 &lt;a href=&#34;http://drupal.stackexchange.com/questions/36542/debug-entityfieldquery&#34; target=&#34;_blank&#34;&gt;stackexchange&lt;/a&gt; 的内容，可以实现 &lt;a href=&#34;https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_query_alter/7&#34; target=&#34;_blank&#34;&gt;hook_query_alter()&lt;/a&gt; 结合 &lt;a href=&#34;https://www.drupal.org/project/devel&#34; target=&#34;_blank&#34;&gt;devel&lt;/a&gt;的dpm ，对实体字段查询过程进行排错。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php
function CUSTOMMODULE_query_alter($query) {
  if ($query-&amp;gt;hasTag(&#39;efq_debug&#39;) &amp;amp;&amp;amp; module_exists(&#39;devel&#39;)) {
    dpm((string) $query);
    dpm($query-&amp;gt;arguments());
  }
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;当你往自己的模块中加入了这个函数，就可以利用addTag&lt;code&gt;(&#39;efq_debug&#39;)&lt;/code&gt;来扩展这个查询：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;&amp;lt;?php
$q = new EntityFieldQuery;
$q-&amp;gt;entityCondition(&#39;entity_type&#39;, &#39;node&#39;);
  -&amp;gt;addTag(&#39;efq_debug&#39;);
  -&amp;gt;execute();
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;相关资源&#34;&gt;相关资源&lt;/h2&gt;

&lt;h3 id=&#34;代码实例&#34;&gt;代码实例&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;modules\simpletest\tests\entity_query.test中的EntityFieldQuery测试。&lt;/li&gt;
&lt;li&gt;在核心和其他模块中利用grep/search搜索&lt;code&gt;new EntityFieldQuery()&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;文章和教程&#34;&gt;文章和教程&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://treehouseagency.com/blog/neil-hastings/2011/09/06/building-energygov-without-views&#34; target=&#34;_blank&#34;&gt;没有 views 的 Energy.gov&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://drupal.org/node/916776&#34; target=&#34;_blank&#34;&gt;Drupal.org 的相关论题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://treehouseagency.com/blog/tim-cosgrove/2012/02/16/entityfieldquery-let-drupal-do-heavy-lifting-pt-1&#34; target=&#34;_blank&#34;&gt;EntityFieldQuery: Let Drupal Do The Heavy Lifting (Pt 1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://treehouseagency.com/blog/tim-cosgrove/2012/02/28/entityfieldquery-let-drupal-do-heavy-lifting-pt-2&#34; target=&#34;_blank&#34;&gt;EntityFieldQuery: Let Drupal Do The Heavy Lifting (Pt 2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.phase2technology.com/blog/or-queries-with-entityfieldquery&#34; target=&#34;_blank&#34;&gt;EntityFieldQuery中的OR查询&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://timonweb.com/loading-only-one-field-from-an-entity-or-node&#34; target=&#34;_blank&#34;&gt;从一个实体或节点中只获取一个字段&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;其他资源&#34;&gt;其他资源&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://api.drupal.org/api/drupal/includes--entity.inc/class/EntityFieldQuery/7&#34; target=&#34;_blank&#34;&gt;api.drupal.org 上的 EntityFieldQuery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
