how to list entities by metadata with 2 options

I have a plugin that I have created and I am trying to list out entities using metadata... this is my current function that works fine:

list_entities_from_metadata_multi(array('update_type' => '1','status'=>'1'), 'object','updates', 0, 10,false, false, true);

what I really want to do is list all entities that have update_type = 1 OR 2 ... but I am not sure how to do it... I have tried to find online, but just can't figure it out.

appreciate your help

-Justin

  • thanks... I will go back and look into it, I came across it before but I just got a little lost in the doc

  • @K

    * metadata_name_value_pairs => NULL|ARR (name = 'name', value => 'value', 'operand' => '=', 'case_sensitive' => TRUE) entries.
    * Currently if multiple values are sent via an array (value => array('value1', 'value2') the pair's operand will be forced to "IN".
    * metadata_name_value_pairs_operator => NULL|STR The operator to use for combining (name = value) OPERATOR (name = value); default AND

  • fyi: I am pretty new to all this... (if you couldn't already tell)

    With that said-

    what is the best way of finding specific documentation with elgg? I have been googling to find answers up until now, but now I can't seem to find the specific documentation on elgg_get_entities_from_metadata() . Thanks again for the help.

     

  • ok...

    I have changed the code to:

    list_entities_from_metadata_multi(array('metadata_name_value_pairs'=>array(array('status'=>'1','update_type'=>array('1','2'),'operand'=> 'IN'))), 'object','updates', 0, 10,false, false, true);        

    it now gives me every update_type... 1,2,3,4,5,6... all of them

  • Kenyonj, one of the approaches would be to create a method that would support building of OR's for metadata. Below I attach a method I use to select from multiple metadata (although without OR's), maybe it will be usefull to you (the method is From Elgg 1.6, which has more straight-forward SQL methods):

     

     

    /**
     *
     * @global Array $CONFIG
     * @param Array $meta_array Is a multidimensional array with the list of
    metadata to filter.
     * For each metadata you have to provide 3 values:
     * - name of metadata
     * - value of metadata
     * - operand ( <, >, <=, >=, =, like)
     * For example
     *      $meta_array = array(
     *              array(
     *                  'name'=>'my_metadatum',
     *                  'operand'=>'>=',
     *                  'value'=>'my value'
     *              )
     *      )
     * @param String $entity_type
     * @param String $entity_subtype
     * @param Boolean $count
     * @param Integer $owner_guid
     * @param Integer $container_guid
     * @param Integer $limit
     * @param Integer $offset
     * @param String $order_by "Order by" SQL string. If you want to sort by
    metadata string,
     * possible values are vN.string, where N is the first index of $meta_array,
     * hence our example is $order by = 'v1.string ASC'
     * @param Integer $site_guid
     * @return Mixed Array of entities or false
     *
     */
    if (!function_exists("vazco_get_entities_from_metadata_by_value")){
       
        function vazco_get_entities_from_metadata_by_value($meta_array, $entity_type = "",$entity_subtype = "", $count = false
        , $owner_guid = 0, $container_guid = 0, $limit = 10,$offset = 0,$order_by = "", $site_guid = 0, $min_time = 0, $max_time = 0, $access_id = "")
        {
            global $CONFIG;

            // ORDER BY
            if ($order_by == "") $order_by = "e.time_created desc";
            $order_by = sanitise_string($order_by);

            $where = array();

            // Filetr by metadata
            $mindex = 1; // Starting index of joined metadata/metastring tables
            $join_meta = "";
            $query_access = "";
            foreach($meta_array as $meta) {
                $join_meta .= "JOIN {$CONFIG->dbprefix}metadata m{$mindex} on e.guid = m{$mindex}.entity_guid ";
                $join_meta .= "JOIN {$CONFIG->dbprefix}metastrings v{$mindex} on v{$mindex}.id = m{$mindex}.value_id ";

                $meta_n = get_metastring_id($meta['name']);
                $where[] = "m{$mindex}.name_id='$meta_n'";

                if (strtolower($meta['operand']) == "like"){
                    // "LIKE" search
                    $where[] = "v{$mindex}.string LIKE ('".$meta['value']."') ";
                }elseif(strtolower($meta['operand']) == "in"){
                    // TO DO - "IN" search
                }elseif($meta['operand'] != ''){
                    // Simple operand search
                    $where[] = "v{$mindex}.string".$meta['operand']."'".$meta['value']."'";
                }

                $query_access .= ' and ' . get_access_sql_suffix("m{$mindex}");
    // Add access controls

                $mindex++;
            }

            $limit = (int)$limit;
            $offset = (int)$offset;

            if ((is_array($owner_guid) && (count($owner_guid)))) {
                foreach($owner_guid as $key => $guid) {
                    $owner_guid[$key] = (int) $guid;
                }
            } else {
                $owner_guid = (int) $owner_guid;
            }

            if ((is_array($container_guid) && (count($container_guid)))) {
                foreach($container_guid as $key => $guid) {
                    $container_guid[$key] = (int) $guid;
                }
            } else {
                $container_guid = (int) $container_guid;
            }

            $site_guid = (int) $site_guid;
            if ($site_guid == 0)
                $site_guid = $CONFIG->site_guid;

            $entity_type = sanitise_string($entity_type);
            if ($entity_type!="")
                $where[] = "e.type='$entity_type'";

            $entity_subtype = get_subtype_id($entity_type, $entity_subtype);
            if ($entity_subtype)
                $where[] = "e.subtype=$entity_subtype";

            if ($site_guid > 0)
                $where[] = "e.site_guid = {$site_guid}";

            if (is_array($owner_guid)) {
                $where[] = "e.owner_guid in (".implode(",",$owner_guid).")";
            } else if ($owner_guid > 0) {
                $where[] = "e.owner_guid = {$owner_guid}";
            }

            if (is_array($container_guid)) {
                $where[] = "e.container_guid in (".implode(",",$container_guid).")";
            } else if ($container_guid > 0)
                $where[] = "e.container_guid = {$container_guid}";

            if ($min_time > 0) {
                $where[] = "e.time_created > {$min_time}";
            }
            if ($max_time > 0) {
                $where[] = "e.time_created < {$max_time}";
            }
               
            if ($access_id != "") {
                $where[] = "e.access_id = {$access_id}";
            }
           
            if (!$count) {
                $query = "SELECT distinct e.* ";
            } else {
                $query = "SELECT count(distinct e.guid) as total ";
            }

            $query .= "FROM {$CONFIG->dbprefix}entities e ";
            $query .= $join_meta;

            $query .= "  WHERE ";
            foreach ($where as $w)
                $query .= " $w and ";
            $query .= get_access_sql_suffix("e"); // Add access controls
            $query .= $query_access;
       
            if (!$count) {
                $query .= " order by $order_by limit $offset, $limit"; // Add order and limit
                echo $query,'<br>',time();
               
                return get_data($query, "entity_row_to_elggstar");
            } else {
                $row = get_data_row($query);
                //echo $query.mysql_error().__FILE__.__LINE__;
                if ($row)
                    return $row->total;
            }
            return false;
        }
    }

  • I recommend against using Mike's function as its not part of the core and elgg_get_entities_from_metadata() seems to be a better function anyway.

    Here is the documentation for elgg_get_entities_from_metadata():

    http://reference.elgg.org/engine_2lib_2metadata_8php.html#aec4b6f0b9565e3554acb9b39ef34a2ac

    It has a companion function elgg_list_entities_from_metadata().

     

  • I do not follow the confoosing multiple mutiple posts.
    the sample code i posted earlier is from a live production website and the shitz works  correctly ;-)

    elgg_get_entities_from_metadata
        (
            array('metadata_name_value_pairs' => array
                    (
                        'toId' => $_SESSION['user']->guid,
                        'readYet' => 0,
                        'msg' => 1
                    )
                    ,'types' => 'object'
                    ,'subtypes' => 'messages'
                    ,'owner_guid' => $_SESSION['user']->guid
                    ,'limit' => 9999
                )
        );

     

  • @DhrupDeScoop

    I would be perfectly happy to use that code, but I don't see how its pull multiple values for one metadata name? I understand its from a live site, could you explain how that would work for my situation? thanks.

  • I would like to use:

    metadata_name_value_pairs => NULL|ARR (name => 'name', value => 'value', 'operand' => '=', 'case_sensitive' => TRUE) entries. Currently if multiple values are sent via an array (value => array('value1', 'value2') the pair's operand will be forced to "IN".

    can you explain how this can be interpreted? or maybe an example... by reading that I am not really sure of the code syntax.

    thanks

  • i don't know if it's as i will use it tomorrow but:

    elgg_get_entities_from_metadata
    (
       array('types'=>'object',
               'subtypes'=>'data',
               'limit'=>1,
               'metadata_names' =>array('name'),
               'metadata_values' =>array('asdf','jkli'),
               'owner_guid'=>get_loggedin_userid()
              )
    );

    here u have multiple values of a metaname

    ;)