The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Build.PL 45
Changes 020
LICENSE 11
MANIFEST 212
MANIFEST.SKIP 03
META.json 091
META.yml 34
Makefile.PL 104
README 2710
cpanfile 045
dist.ini 219
examples/all_favorite_counts_per_dist.pl 025
examples/authors_blogs.pl 022
examples/es_filter.pl 029
examples/fields-filter.pl 014
examples/mirror.pl 014
examples/rating.pl 014
examples/top20_favorite_distributions.pl 027
lib/MetaCPAN/Client/Author.pm 22
lib/MetaCPAN/Client/Distribution.pm 22
lib/MetaCPAN/Client/Favorite.pm 22
lib/MetaCPAN/Client/File.pm 22
lib/MetaCPAN/Client/Mirror.pm 0117
lib/MetaCPAN/Client/Module.pm 22
lib/MetaCPAN/Client/Pod.pm 212
lib/MetaCPAN/Client/Rating.pm 22
lib/MetaCPAN/Client/Release.pm 22
lib/MetaCPAN/Client/Request.pm 834
lib/MetaCPAN/Client/ResultSet.pm 33
lib/MetaCPAN/Client/Role/Entity.pm 22
lib/MetaCPAN/Client.pm 39101
t/00-compile.t 23
32 files changed (This is a version diff) 363635
@@ -1,5 +1,5 @@
 
-# This file was automatically generated by Dist::Zilla::Plugin::ModuleBuild v5.025.
+# This file was automatically generated by Dist::Zilla::Plugin::ModuleBuild v5.035.
 use strict;
 use warnings;
 
@@ -20,7 +20,7 @@ my %module_build_args = (
     "Mickey Nasriachi <mickey\@cpan.org>"
   ],
   "dist_name" => "MetaCPAN-Client",
-  "dist_version" => "1.008001",
+  "dist_version" => "1.013000",
   "license" => "perl",
   "module_name" => "MetaCPAN::Client",
   "recommends" => {},
@@ -35,6 +35,7 @@ my %module_build_args = (
     "Search::Elasticsearch" => "1.10",
     "Search::Elasticsearch::Scroll" => 0,
     "Try::Tiny" => 0,
+    "perl" => "5.008",
     "strict" => 0,
     "warnings" => 0
   },
@@ -47,7 +48,7 @@ my %module_build_args = (
     "Test::More" => 0,
     "Test::Requires" => 0,
     "base" => 0,
-    "perl" => "5.006"
+    "perl" => "5.008"
   }
 );
 
@@ -61,7 +62,7 @@ my %fallback_build_requires = (
   "Test::More" => 0,
   "Test::Requires" => 0,
   "base" => 0,
-  "perl" => "5.006"
+  "perl" => "5.008"
 );
 
 
@@ -1,5 +1,25 @@
 Revision history for MetaCPAN-Client (previously MetaCPAN-API)
 
+1.013000    25.04.15
+            * GH #34 Use Travis for CI (oalders)
+            * GH #35 Improve Kwalitee + test improvements (oalders)
+
+1.012000    09.04.15
+            * GH #33 added Mirror type and support for mirrors search in 'all' queries (mickeyn)
+            * GH #33 support 'ratings' search in 'all' queries (mickeyn)
+            * more example scripts: facets, top favorites, all authors blogs (mickeyn)
+            * cleanup & doc updates (Gabor Szabo, mickeyn)
+
+1.011000    27.01.15
+            * support 'favorites' type and 'facets' key param in 'all' queries (mickeyn) 
+
+1.010000    23.01.15
+            * support wildcard-only value in complex search (mickeyn)
+            * support raw ElasticSearch filters in 'all' queries (mickeyn)
+
+1.009000    11.01.15
+            * GH #25 (RT #99499): added support for 'fields' filtering (mickeyn, oalders)
+
 1.008001    01.01.15
             * Happy new year!
             * Correct Meta resources for the repo.
@@ -22,7 +22,7 @@ This is free software, licensed under:
                      Version 1, February 1989
 
  Copyright (C) 1989 Free Software Foundation, Inc.
- 51 Franklin St, Suite 500, Boston, MA  02110-1335  USA
+ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
@@ -1,33 +1,43 @@
-# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.025.
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.035.
 Build.PL
 Changes
 LICENSE
 MANIFEST
+MANIFEST.SKIP
+META.json
 META.yml
 Makefile.PL
-README
+cpanfile
 dist.ini
+examples/all_favorite_counts_per_dist.pl
 examples/author-country.pl
 examples/author.pl
 examples/author_releases.pl
+examples/authors_blogs.pl
 examples/complex-either-and.pl
 examples/complex-either-not.pl
 examples/complex-nested-either-and.pl
 examples/complex.pl
 examples/distribution.pl
+examples/es_filter.pl
+examples/fields-filter.pl
+examples/mirror.pl
 examples/module.pl
 examples/pod.pl
+examples/rating.pl
 examples/recent.pl
 examples/recent_today.pl
 examples/release.pl
 examples/rev_deps-recursive.pl
 examples/rev_deps.pl
+examples/top20_favorite_distributions.pl
 examples/totals.pl
 lib/MetaCPAN/Client.pm
 lib/MetaCPAN/Client/Author.pm
 lib/MetaCPAN/Client/Distribution.pm
 lib/MetaCPAN/Client/Favorite.pm
 lib/MetaCPAN/Client/File.pm
+lib/MetaCPAN/Client/Mirror.pm
 lib/MetaCPAN/Client/Module.pm
 lib/MetaCPAN/Client/Pod.pm
 lib/MetaCPAN/Client/Rating.pm
@@ -0,0 +1,3 @@
+cpanfile.snapshot
+local
+MetaCPAN-Client*
@@ -0,0 +1,91 @@
+{
+   "abstract" : "A comprehensive, DWIM-featured client to the MetaCPAN API",
+   "author" : [
+      "Sawyer X <xsawyerx@cpan.org>",
+      "Mickey Nasriachi <mickey@cpan.org>"
+   ],
+   "dynamic_config" : 0,
+   "generated_by" : "Dist::Zilla version 5.035, CPAN::Meta::Converter version 2.142060",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : "2"
+   },
+   "name" : "MetaCPAN-Client",
+   "no_index" : {
+      "file" : [
+         "README.pod"
+      ]
+   },
+   "prereqs" : {
+      "build" : {
+         "requires" : {
+            "Module::Build" : "0.28"
+         }
+      },
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0",
+            "Module::Build" : "0.28"
+         }
+      },
+      "develop" : {
+         "requires" : {
+            "HTTP::Tiny::Mech" : "0",
+            "Pod::Coverage::TrustPod" : "0",
+            "Test::Pod" : "1.41",
+            "Test::Pod::Coverage" : "1.08",
+            "WWW::Mechanize::Cached" : "1.48"
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "Carp" : "0",
+            "HTTP::Tiny" : "0",
+            "JSON::MaybeXS" : "0",
+            "Moo" : "0",
+            "Moo::Role" : "0",
+            "Safe::Isa" : "0",
+            "Search::Elasticsearch" : "1.10",
+            "Search::Elasticsearch::Scroll" : "0",
+            "Try::Tiny" : "0",
+            "perl" : "5.008",
+            "strict" : "0",
+            "warnings" : "0"
+         }
+      },
+      "test" : {
+         "recommends" : {
+            "HTTP::Tiny::Mech" : "0",
+            "WWW::Mechanize::Cached" : "1.48"
+         },
+         "requires" : {
+            "File::Spec" : "0",
+            "IO::Handle" : "0",
+            "IPC::Open3" : "0",
+            "Test::Fatal" : "0",
+            "Test::More" : "0",
+            "Test::Requires" : "0",
+            "base" : "0",
+            "perl" : "5.008"
+         }
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "web" : "https://github.com/CPAN-API/metacpan-client/issues"
+      },
+      "repository" : {
+         "type" : "git",
+         "url" : "git://github.com/CPAN-API/metacpan-client.git",
+         "web" : "https://github.com/CPAN-API/metacpan-client"
+      },
+      "x_IRC" : "irc://irc.perl.org/#metacpan",
+      "x_WebIRC" : "https://chat.mibbit.com/#metacpan@irc.perl.org"
+   },
+   "version" : "1.013000"
+}
+
@@ -12,12 +12,12 @@ build_requires:
   Test::More: 0
   Test::Requires: 0
   base: 0
-  perl: 5.006
+  perl: 5.008
 configure_requires:
   ExtUtils::MakeMaker: 0
   Module::Build: 0.28
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.025, CPAN::Meta::Converter version 2.142690'
+generated_by: 'Dist::Zilla version 5.035, CPAN::Meta::Converter version 2.142060'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -36,6 +36,7 @@ requires:
   Search::Elasticsearch: 1.10
   Search::Elasticsearch::Scroll: 0
   Try::Tiny: 0
+  perl: 5.008
   strict: 0
   warnings: 0
 resources:
@@ -43,4 +44,4 @@ resources:
   WebIRC: https://chat.mibbit.com/#metacpan@irc.perl.org
   bugtracker: https://github.com/CPAN-API/metacpan-client/issues
   repository: git://github.com/CPAN-API/metacpan-client.git
-version: 1.008001
+version: 1.013000
@@ -1,14 +1,11 @@
-
-# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.025.
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.035.
 use strict;
 use warnings;
 
-use 5.006;
+use 5.008;
 
 use ExtUtils::MakeMaker;
 
-
-
 my %WriteMakefileArgs = (
   "ABSTRACT" => "A comprehensive, DWIM-featured client to the MetaCPAN API",
   "AUTHOR" => "Sawyer X <xsawyerx\@cpan.org>, Mickey Nasriachi <mickey\@cpan.org>",
@@ -22,7 +19,7 @@ my %WriteMakefileArgs = (
   "DISTNAME" => "MetaCPAN-Client",
   "EXE_FILES" => [],
   "LICENSE" => "perl",
-  "MIN_PERL_VERSION" => "5.006",
+  "MIN_PERL_VERSION" => "5.008",
   "NAME" => "MetaCPAN::Client",
   "PREREQ_PM" => {
     "Carp" => 0,
@@ -46,7 +43,7 @@ my %WriteMakefileArgs = (
     "Test::Requires" => 0,
     "base" => 0
   },
-  "VERSION" => "1.008001",
+  "VERSION" => "1.013000",
   "test" => {
     "TESTS" => "t/*.t t/api/*.t"
   }
@@ -87,6 +84,3 @@ delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
   unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
 
 WriteMakefile(%WriteMakefileArgs);
-
-
-
@@ -1,271 +0,0 @@
-NAME
-    MetaCPAN::Client - A comprehensive, DWIM-featured client to the MetaCPAN
-    API
-
-VERSION
-    version 1.008001
-
-SYNOPSIS
-        # simple usage
-        my $mcpan  = MetaCPAN::Client->new();
-        my $author = $mcpan->author('XSAWYERX');
-        my $dist   = $mcpan->distribution('MetaCPAN-Client');
-
-        # advanced usage with cache (contributed by Kent Fredric)
-        use CHI;
-        use WWW::Mechanize::Cached;
-        use HTTP::Tiny::Mech;
-        use MetaCPAN::Client;
-
-        my $mcpan = MetaCPAN::Client->new(
-          ua => HTTP::Tiny::Mech->new(
-            mechua => WWW::Mechanize::Cached->new(
-              cache => CHI->new(
-                driver   => 'File',
-                root_dir => '/tmp/metacpan-cache',
-              ),
-            ),
-          ),
-        );
-
-        # now $mcpan caches results
-
-DESCRIPTION
-    This is a hopefully-complete API-compliant client to MetaCPAN
-    (<https://metacpan.org>) with DWIM capabilities, to make your life
-    easier.
-
-ATTRIBUTES
-  request
-    Internal attribute representing the request object making the request to
-    MetaCPAN and analyzing the results. You probably don't want to set this,
-    nor should you have any usage of it.
-
-  ua
-    If provided, MetaCPAN::Client::Request will use the user agent object
-    instead of the default, which is HTTP::Tiny.
-
-    Then it can be used to fetch the user agent object used by
-    MetaCPAN::Client::Request.
-
-METHODS
-  author
-        my $author = $mcpan->author('XSAWYERX');
-        my $author = $mcpan->author($search_spec);
-
-    Finds an author by either its PAUSE ID or by a search spec defined by a
-    hash reference. Since it is common to many other searches, it is
-    explained below under "SEARCH SPEC".
-
-    Return a MetaCPAN::Client::Author object on a simple search (PAUSE ID),
-    or a MetaCPAN::Client::ResultSet object propagated with
-    MetaCPAN::Client::Author objects on a complex (search spec based)
-    search.
-
-  module
-        my $module = $mcpan->module('MetaCPAN::Client');
-        my $module = $mcpan->module($search_spec);
-
-    Finds a module by either its module name or by a search spec defined by
-    a hash reference. Since it is common to many other searches, it is
-    explained below under "SEARCH SPEC".
-
-    Return a MetaCPAN::Client::Module object on a simple search (module
-    name), or a MetaCPAN::Client::ResultSet object propagated with
-    MetaCPAN::Client::Module objects on a complex (search spec based)
-    search.
-
-  distribution
-        my $dist = $mcpan->distribution('MetaCPAN-Client');
-        my $dist = $mcpan->distribution($search_spec);
-
-    Finds a distribution by either its distribution name or by a search spec
-    defined by a hash reference. Since it is common to many other searches,
-    it is explained below under "SEARCH SPEC".
-
-    Return a MetaCPAN::Client::Distribution object on a simple search
-    (distribution name), or a MetaCPAN::Client::ResultSet object propagated
-    with MetaCPAN::Client::Distribution objects on a complex (search spec
-    based) search.
-
-  file
-    Return a MetaCPAN::Client::File object.
-
-  favorite
-    Return a MetaCPAN::Client::Favorite object.
-
-  rating
-    Return a MetaCPAN::Client::Rating object.
-
-  release
-        my $release = $mcpan->release('MetaCPAN-Client');
-        my $release = $mcpan->release($search_spec);
-
-    Finds a release by either its distribution name or by a search spec
-    defined by a hash reference. Since it is common to many other searches,
-    it is explained below under "SEARCH SPEC".
-
-    Return a MetaCPAN::Client::Release object on a simple search (release
-    name), or a MetaCPAN::Client::ResultSet object propagated with
-    MetaCPAN::Client::Release objects on a complex (search spec based)
-    search.
-
-  reverse_dependencies
-        my $deps = $mcpan->reverse_dependencies('ElasticSearch');
-
-    all MetaCPAN::Client::Release objects of releases that are dependent on
-    a given module, returned as MetaCPAN::Client::ResultSet.
-
-  rev_deps
-    Alias to "reverse_dependencies" described above.
-
-  recent
-        my $recent = $mcpan->recent(10);
-        my $recent = $mcpan->recent('today');
-
-    return the latest N releases, or all releases from today.
-
-    returns a MetaCPAN::Client::ResultSet of MetaCPAN::Client::Release.
-
-  pod
-    Get POD for given file/module name. returns a MetaCPAN::Client::Pod
-    object, which supports various output formats (html, plain, x_pod &
-    x_markdown).
-
-        my $pod = $mcpan->pod('Moo')->html;
-
-  all
-    Retrieve all matches for authors/modules/distributions or releases.
-
-        my $all_releases = $mcpan->all('releases')
-
-  BUILDARGS
-    Internal construction wrapper. Do not use.
-
-SEARCH SPEC
-    The hash-based search spec is common to many searches. It is quite
-    feature-rich and allows to disambiguate different types of searches.
-
-    Basic search specs just contain a hash of keys and values:
-
-        my $author = $mcpan->author( { name => 'Micha Nasriachi' } );
-
-        # the following is the same as ->author('MICKEY')
-        my $author = $mcpan->author( { pauseid => 'MICKEY' } );
-
-        # find all people named Dave, not covering Davids
-        # will return a resultset
-        my $daves = $mcpan->author( { name => 'Dave *' } );
-
-  OR
-    If you want to do a more complicated query that has an *OR* condition,
-    such as "this or that", you can use the following syntax with the
-    "either" key:
-
-        # any author named "Dave" or "David"
-        my $daves = $mcpan->author( {
-            either => [
-                { name => 'Dave *'  },
-                { name => 'David *' },
-            ]
-        } );
-
-  AND
-    If you want to do a more complicated query that has an *AND* condition,
-    such as "this and that", you can use the following syntax with the "all"
-    key:
-
-        # any users named 'John' with a Gmail account
-        my $johns = $mcpan->author( {
-            all => [
-                { name  => 'John *'     },
-                { email => '*gmail.com' },
-            ]
-        } );
-
-    If you want to do something even more complicated, You can also nest
-    your queries, e.g.:
-
-        my $gmail_daves_or_cpan_sams = $mcpan->author( {
-            either => [
-                { all => [ { name => 'Dave *'  },
-                           { email => '*gmail.com' } ]
-                },
-                { all => [ { name => 'Sam *' },
-                           { email => '*cpan.org' } ]
-                },
-            ],
-        } );
-
-  NOT
-    If you want to filter out some of the results of an either/all query
-    adding a *NOT* filter condition, such as "not these", you can use the
-    following syntax with the "not" key:
-
-        # any author named "Dave" or "David"
-        my $daves = $mcpan->author( {
-            either => [
-                { name => 'Dave *'  },
-                { name => 'David *' },
-            ],
-            not => [
-                { email => '*gmail.com' },
-            ],
-        } );
-
-DESIGN
-    This module has three purposes:
-
-    *   Provide 100% of the MetaCPAN API
-
-        This module will be updated regularly on every MetaCPAN API change,
-        and intends to provide the user with as much of the API as possible,
-        no shortcuts. If it's documented in the API, you should be able to
-        do it.
-
-        Because of this design decision, this module has an official
-        MetaCPAN namespace with the blessing of the MetaCPAN developers.
-
-        Notice this module currently only provides the beta API, not the old
-        soon-to-be-deprecated API.
-
-    *   Be lightweight, to allow flexible usage
-
-        While many modules would help make writing easier, it's important to
-        take into account how they affect your compile-time, run-time,
-        overall memory consumption, and CPU usage.
-
-        By providing a slim interface implementation, more users are able to
-        use this module, such as long-running processes (like daemons), CLI
-        or GUI applications, cron jobs, and more.
-
-    *   DWIM
-
-        While it's possible to access the methods defined by the API spec,
-        there's still a matter of what you're really trying to achieve. For
-        example, when searching for *"Dave"*, you want to find both *Dave
-        Cross* and *Dave Rolsky* (and any other *Dave*), but you also want
-        to search for a PAUSE ID of *DAVE*, if one exists.
-
-        This is where DWIM comes in. This module provides you with
-        additional generic methods which will try to do what they think you
-        want.
-
-        Of course, this does not prevent you from manually using the API
-        methods. You still have full control over that, if that's what you
-        wish.
-
-        You can (and should) read up on the general methods, which will
-        explain how their DWIMish nature works, and what searches they run.
-
-AUTHORS
-    *   Sawyer X <xsawyerx@cpan.org>
-
-    *   Mickey Nasriachi <mickey@cpan.org>
-
-COPYRIGHT AND LICENSE
-    This software is copyright (c) 2015 by Sawyer X.
-
-    This is free software; you can redistribute it and/or modify it under
-    the same terms as the Perl 5 programming language system itself.
-
@@ -0,0 +1,45 @@
+requires "Carp" => "0";
+requires "HTTP::Tiny" => "0";
+requires "JSON::MaybeXS" => "0";
+requires "Moo" => "0";
+requires "Moo::Role" => "0";
+requires "Safe::Isa" => "0";
+requires "Search::Elasticsearch" => "1.10";
+requires "Search::Elasticsearch::Scroll" => "0";
+requires "Try::Tiny" => "0";
+requires "perl" => "5.008";
+requires "strict" => "0";
+requires "warnings" => "0";
+
+on 'build' => sub {
+  requires "Module::Build" => "0.28";
+};
+
+on 'test' => sub {
+  requires "File::Spec" => "0";
+  requires "IO::Handle" => "0";
+  requires "IPC::Open3" => "0";
+  requires "Test::Fatal" => "0";
+  requires "Test::More" => "0";
+  requires "Test::Requires" => "0";
+  requires "base" => "0";
+  requires "perl" => "5.008";
+};
+
+on 'test' => sub {
+  recommends "HTTP::Tiny::Mech" => "0";
+  recommends "WWW::Mechanize::Cached" => "1.48";
+};
+
+on 'configure' => sub {
+  requires "ExtUtils::MakeMaker" => "0";
+  requires "Module::Build" => "0.28";
+};
+
+on 'develop' => sub {
+  requires "HTTP::Tiny::Mech" => "0";
+  requires "Pod::Coverage::TrustPod" => "0";
+  requires "Test::Pod" => "1.41";
+  requires "Test::Pod::Coverage" => "1.08";
+  requires "WWW::Mechanize::Cached" => "1.48";
+};
@@ -5,20 +5,30 @@ license = Perl_5
 copyright_holder = Sawyer X
 copyright_year   = 2015
 
-version = 1.008001
+version = 1.013000
+
+
+[@Filter]
+-bundle = @Basic
+-remove = GatherDir
 
-[@Basic]
 [PodSyntaxTests]
 [PodCoverageTests]
 [Test::Perl::Critic]
 [Test::Compile]
 
+[Git::GatherDir]
+exclude_filename = cpanfile
+
 [Prereqs]
 Search::Elasticsearch = 1.10
 
 [AutoPrereqs]
 skip = ^t::lib::Functions$
 
+[Prereqs / TestRequires]
+WWW::Mechanize::Cached = 1.48
+
 [Prereqs::Soften]
 module = HTTP::Tiny::Mech
 module = WWW::Mechanize::Cached
@@ -27,14 +37,21 @@ copy_to = develop.requires
 [ModuleBuild]
 [PodWeaver]
 [ReadmeFromPod]
+[MetaJSON]
+[MinimumPerlFast]
 [MetaNoIndex]
 file = README.pod
 
+
 [ReadmeAnyFromPod / pod.root ]
 filename = README.pod
 type     = pod
 location = root
 
+[CPANFile]
+[CopyFilesFromBuild]
+copy = cpanfile
+
 [CheckChangeLog]
 [PkgVersion]
 [MetaResources]
@@ -0,0 +1,25 @@
+use strict;
+use warnings;
+use Data::Printer;
+
+use MetaCPAN::Client;
+
+# All 1+ favorite counts per distributions
+# -- done inefficiently :)
+
+my $mcpan = MetaCPAN::Client->new();
+my $size  = $mcpan->all('favorites')->total;
+my $favs  = $mcpan->all('favorites', {
+    facets => {
+        distribution => {
+            terms => {
+                field => "distribution",
+                size  => $size,
+                order => "reverse_count",
+#                all_terms => "true",
+            }
+        },
+    }
+});
+
+p $favs->facets->{distribution}{terms};
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+
+use MetaCPAN::Client;
+
+my $mcpan = MetaCPAN::Client->new;
+
+my $all_authors = $mcpan->all('authors');
+
+AUTHOR: while ( my $author = $all_authors->next ) {
+
+  BLOG: for my $blog ( @{ $author->blog || [] } ) {
+        $blog and exists $blog->{url} or next BLOG;
+        my $url = $blog->{url};
+
+        my $blogs_csv = ref $url eq 'ARRAY'
+            ? join q{,} => @$url
+            : $url;
+
+        printf "%-10s: %s\n", $author->pauseid, $blogs_csv;
+    }
+}
@@ -0,0 +1,29 @@
+use strict;
+use warnings;
+
+use MetaCPAN::Client;
+
+# use raw ES filter on a { match_all => {} } query
+
+# find 'latest' status releases with at least 700 failing tests
+# which consist at least 50% of their overall number of tests.
+
+my $release = MetaCPAN::Client->new->all(
+    'releases',
+    {
+        es_filter => {
+            and => [
+                { range => { 'tests.fail' => { gte => 700 } } },
+                { term  => { 'status' => 'latest' } }
+            ]
+        },
+
+        fields => [qw/ name tests /],
+    }
+);
+
+while ( my $r = $release->next ) {
+    my $fail = $r->tests->{fail};
+    my $all  = 0; $all += $_ for @{ $r->tests }{qw/pass fail na unknown/};
+    ($fail / $all) >= 0.5 and printf "%4d/%4d: %s\n", $fail, $all, $r->name;
+}
@@ -0,0 +1,14 @@
+
+# examples/fields-filter.pl
+
+use strict;
+use warnings;
+use DDP;
+
+use MetaCPAN::Client;
+
+my $module =
+    MetaCPAN::Client->new->module('Moose',
+                                  { fields => [ qw/ author version / ] });
+
+p $module;
@@ -0,0 +1,14 @@
+
+
+# examples/mirror.pl
+
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $mirrors =
+    MetaCPAN::Client->new->mirror('eutelia.it');
+
+p $mirrors;
+
@@ -0,0 +1,14 @@
+
+# examples/rating.pl
+
+use strict;
+use warnings;
+use DDP;
+
+use MetaCPAN::Client;
+
+my $rating =
+    MetaCPAN::Client->new->rating({ distribution => "Moose" });
+
+p $rating->next;
+
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+use Data::Printer;
+
+use MetaCPAN::Client;
+
+# TOP 20 FAVORITE DISTRIBUTIONS
+
+my $mcpan = MetaCPAN::Client->new();
+my $favs  = $mcpan->all('favorites', {
+    facets => {
+        distribution => {
+            terms => {
+                field => "distribution",
+                size  => 20,
+                order => "count",
+            }
+        },
+    }
+});
+
+print "TOP 20 FAVORITE DISTRIBUTIONS:\n";
+
+my $count = 1;
+for ( @{ $favs->facets->{distribution}{terms} } ) {
+    printf "%3d) %5d  %-20s\n", $count++, @{$_}{qw/count term/};
+}
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Author;
 # ABSTRACT: An Author data object
-$MetaCPAN::Client::Author::VERSION = '1.008001';
+$MetaCPAN::Client::Author::VERSION = '1.013000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -51,7 +51,7 @@ MetaCPAN::Client::Author - An Author data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Distribution;
 # ABSTRACT: A Distribution data object
-$MetaCPAN::Client::Distribution::VERSION = '1.008001';
+$MetaCPAN::Client::Distribution::VERSION = '1.013000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -37,7 +37,7 @@ MetaCPAN::Client::Distribution - A Distribution data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Favorite;
 # ABSTRACT: A Favorite data object
-$MetaCPAN::Client::Favorite::VERSION = '1.008001';
+$MetaCPAN::Client::Favorite::VERSION = '1.013000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -37,7 +37,7 @@ MetaCPAN::Client::Favorite - A Favorite data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::File;
 # ABSTRACT: A File data object
-$MetaCPAN::Client::File::VERSION = '1.008001';
+$MetaCPAN::Client::File::VERSION = '1.013000';
 use Moo;
 use Carp;
 
@@ -60,7 +60,7 @@ MetaCPAN::Client::File - A File data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -0,0 +1,117 @@
+use strict;
+use warnings;
+package MetaCPAN::Client::Mirror;
+# ABSTRACT: A Mirror data object
+$MetaCPAN::Client::Mirror::VERSION = '1.013000';
+use Moo;
+use Carp;
+
+with 'MetaCPAN::Client::Role::Entity';
+
+my @known_fields = qw< name org ftp contact city rsync src ccode
+                       aka_name tz note dnsrr region inceptdate
+                       country location freq continent http
+                       reitredate A_or_CNAME >;
+
+foreach my $field (@known_fields) {
+    has $field => (
+        is      => 'ro',
+        lazy    => 1,
+        default => sub {
+            my $self = shift;
+            return $self->data->{$field};
+        },
+    );
+}
+
+sub _known_fields { return \@known_fields }
+
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+MetaCPAN::Client::Mirror - A Mirror data object
+
+=head1 VERSION
+
+version 1.013000
+
+=head1 
+DESCRIPTION
+
+=head1 
+ATTRIBUTES
+
+=head2 name
+
+=head2 org
+
+=head2 ftp
+
+=head2 contact
+
+=head2 city
+
+=head2 rsync
+
+=head2 src
+
+=head2 ccode
+
+=head2 aka_name
+
+=head2 tz
+
+=head2 note
+
+=head2 dnsrr
+
+=head2 region
+
+=head2 inceptdate
+
+=head2 country
+
+=head2 location
+
+=head2 freq
+
+=head2 continent
+
+=head2 http
+
+=head2 reitredate
+
+=head2 A_or_CNAME
+
+=head1 METHODS
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+Sawyer X <xsawyerx@cpan.org>
+
+=item *
+
+Mickey Nasriachi <mickey@cpan.org>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2015 by Sawyer X.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Module;
 # ABSTRACT: A Module data object
-$MetaCPAN::Client::Module::VERSION = '1.008001';
+$MetaCPAN::Client::Module::VERSION = '1.013000';
 use Moo;
 extends 'MetaCPAN::Client::File';
 
@@ -20,7 +20,7 @@ MetaCPAN::Client::Module - A Module data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Pod;
 # ABSTRACT: A Pod object
-$MetaCPAN::Client::Pod::VERSION = '1.008001';
+$MetaCPAN::Client::Pod::VERSION = '1.013000';
 use Moo;
 
 has name => ( is => 'ro', required => 1 );
@@ -53,7 +53,7 @@ MetaCPAN::Client::Pod - A Pod object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 SYNOPSIS
 
@@ -71,14 +71,24 @@ version 1.008001
 
 =head2 name
 
+The name of the module (probably always the value passed to the pod() method)
+
 =head2 x_pod
 
+The raw pod extracted from the file.
+
 =head2 html
 
+Formatted as an HTML chunk (No <html>...<body>)
+
 =head2 x_markdown
 
+Converted to Markdown.
+
 =head2 plain
 
+Formatted as plain text.
+
 Get the plaintext version of the documentation
 
   $pod = MetaCPAN::Client->new->pod( "MetaCPAN::Client" );
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Rating;
 # ABSTRACT: A Rating data object
-$MetaCPAN::Client::Rating::VERSION = '1.008001';
+$MetaCPAN::Client::Rating::VERSION = '1.013000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -39,7 +39,7 @@ MetaCPAN::Client::Rating - A Rating data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Release;
 # ABSTRACT: A Release data object
-$MetaCPAN::Client::Release::VERSION = '1.008001';
+$MetaCPAN::Client::Release::VERSION = '1.013000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -40,7 +40,7 @@ MetaCPAN::Client::Release - A Release data object
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Request;
 # ABSTRACT: Object used for making requests to MetaCPAN
-$MetaCPAN::Client::Request::VERSION = '1.008001';
+$MetaCPAN::Client::Request::VERSION = '1.013000';
 use Moo;
 use Carp;
 use JSON::MaybeXS qw<decode_json encode_json>;
@@ -89,6 +89,8 @@ sub ssearch {
         ( $self->_has_user_ua ? ( handle => $self->_user_ua ) : () )
     );
 
+    my $body = $self->_build_body($args, $params);
+
     my $scroller = Search::Elasticsearch::Scroll->new(
         es          => $es,
         search_type => 'scan',
@@ -96,7 +98,7 @@ sub ssearch {
         index       => $self->version,
         type        => $type,
         size        => 1000,
-        body        => $self->_build_body($args),
+        body        => $body,
         %{ $params },
     );
 
@@ -132,14 +134,19 @@ sub _decode_result {
 }
 
 sub _build_body {
-    my $self  = shift;
-    my $args  = shift;
+    my $self   = shift;
+    my $args   = shift;
+    my $params = shift;
 
     my $query = $args->{__MATCH_ALL__}
         ? { match_all => {} }
         : _build_query_rec($args);
 
-    return +{ query => $query };
+    return +{
+        query => $query,
+        _read_filters($params),
+        _read_facets($params)
+    };
 }
 
 my %key2es = (
@@ -148,6 +155,24 @@ my %key2es = (
     not    => 'must_not',
 );
 
+sub _read_facets {
+    my $params = shift;
+
+    my $facets = delete $params->{facets};
+    ref($facets) or return ();
+
+    return ( facets => $facets );
+}
+
+sub _read_filters {
+    my $params = shift;
+
+    my $filter = delete $params->{es_filter};
+    ref($filter) or return ();
+
+    return ( filter => $filter );
+}
+
 sub _build_query_rec {
     my $args  = shift;
     ref $args eq 'HASH' or croak 'query args must be a hash';
@@ -180,11 +205,12 @@ sub _build_query_element {
         or croak 'Wrong number of keys in query element';
 
     my ($key) = keys %{$args};
+    my $val = $args->{$key};
 
-    ! ref( $args->{$key} ) and $args->{$key} =~ /\w/
+    !ref($val) and $val =~ /[\w\*]/
         or croak 'Wrong type of query arguments';
 
-    my $wildcard = $args->{$key} =~ /[*?]/;
+    my $wildcard = $val =~ /[*?]/;
     my $qtype    = $wildcard ? 'wildcard' : 'term';
 
     return +{ $qtype => $args };
@@ -205,7 +231,7 @@ MetaCPAN::Client::Request - Object used for making requests to MetaCPAN
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 ATTRIBUTES
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::ResultSet;
 # ABSTRACT: A Result Set
-$MetaCPAN::Client::ResultSet::VERSION = '1.008001';
+$MetaCPAN::Client::ResultSet::VERSION = '1.013000';
 use Moo;
 use Carp;
 
@@ -11,7 +11,7 @@ has type => (
     isa      => sub {
         croak 'Invalid type' unless
             grep { $_ eq $_[0] } qw<author distribution favorite
-                                   file module rating release>;
+                                   file module rating release mirror>;
     },
     required => 1,
 );
@@ -89,7 +89,7 @@ MetaCPAN::Client::ResultSet - A Result Set
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Role::Entity;
 # ABSTRACT: A role for MetaCPAN entities
-$MetaCPAN::Client::Role::Entity::VERSION = '1.008001';
+$MetaCPAN::Client::Role::Entity::VERSION = '1.013000';
 use Moo::Role;
 
 has data => (
@@ -47,7 +47,7 @@ MetaCPAN::Client::Role::Entity - A role for MetaCPAN entities
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client;
 # ABSTRACT: A comprehensive, DWIM-featured client to the MetaCPAN API
-$MetaCPAN::Client::VERSION = '1.008001';
+$MetaCPAN::Client::VERSION = '1.013000';
 use Moo;
 use Carp;
 
@@ -15,6 +15,7 @@ use MetaCPAN::Client::Favorite;
 use MetaCPAN::Client::Pod;
 use MetaCPAN::Client::Rating;
 use MetaCPAN::Client::Release;
+use MetaCPAN::Client::Mirror;
 use MetaCPAN::Client::ResultSet;
 
 has request => (
@@ -23,16 +24,16 @@ has request => (
 );
 
 my @supported_searches = qw<
-    author distribution favorite module rating release
+    author distribution favorite module rating release mirror
 >;
 
 sub BUILDARGS {
     my ( $class, %args ) = @_;
 
     $args{'request'} ||= MetaCPAN::Client::Request->new(
-        ( ua => $args{'ua'} ) x !! $args{'ua'},
-        $args{domain}  ? ( domain => $args{domain} )   : (),
-        $args{version} ? ( version => $args{version} ) : (),
+        ( ua      => $args{ua}      )x!! $args{ua},
+        ( domain  => $args{domain}  )x!! $args{domain},
+        ( version => $args{version} )x!! $args{version},
     );
 
     return \%args;
@@ -79,13 +80,6 @@ sub pod {
     return MetaCPAN::Client::Pod->new({ name => $name });
 }
 
-#
-# $api->rating({ dist => "Moose" })
-#   is equal to http://api.metacpan.org/v0/favorite/_search?q=distribution:Moose
-#
-# $api->rating({ author => "DOY" })
-#   is equal to http://api.metacpan.org/v0/favorite/_search?q=author:DOY
-#
 sub favorite {
     my $self   = shift;
     my $args   = shift;
@@ -97,13 +91,6 @@ sub favorite {
     return $self->_search( 'favorite', $args, $params );
 }
 
-#
-# $api->rating({ rating => "4.0" })
-#   is equal to http://api.metacpan.org/v0/rating/_search?q=rating:4.0
-#
-# $api->rating({ distribution => "Moose" })
-#   is equal to http://api.metacpan.org/v0/rating/_search?q=distribution:Moose
-#
 sub rating {
     my $self   = shift;
     my $args   = shift;
@@ -115,10 +102,6 @@ sub rating {
     return $self->_search( 'rating', $args, $params );
 }
 
-#
-# $api->release({ author => "XSAWYERX" })
-#   is equal to http://api.metacpan.org/v0/release/_search?q=author:XSAWYERX
-#
 sub release {
     my $self   = shift;
     my $arg    = shift;
@@ -127,6 +110,14 @@ sub release {
     return $self->_get_or_search( 'release', $arg, $params );
 }
 
+sub mirror {
+    my $self   = shift;
+    my $arg    = shift;
+    my $params = shift;
+
+    return $self->_get_or_search( 'mirror', $arg, $params );
+}
+
 sub reverse_dependencies {
     my $self = shift;
     my $dist = shift;
@@ -155,17 +146,19 @@ sub recent {
 }
 
 sub all {
-    my $self = shift;
-    my $type = shift;
+    my $self   = shift;
+    my $type   = shift;
+    my $params = shift;
 
-    my $match_all = { __MATCH_ALL__ => 1 };
+    grep { $type eq $_ } qw/ authors distributions modules releases
+                             favorites ratings mirrors /
+        or croak "all: unsupported type";
+    $type =~ s/s$//;
 
-    $type eq 'authors'       and return $self->author( $match_all );
-    $type eq 'distributions' and return $self->distribution( $match_all );
-    $type eq 'modules'       and return $self->module( $match_all );
-    $type eq 'releases'      and return $self->release( $match_all );
+    $params and ref($params) ne 'HASH'
+        and croak "all: params must be a hashref";
 
-    croak "all: unsupported type";
+    return $self->$type( { __MATCH_ALL__ => 1 }, $params );
 }
 
 ###
@@ -173,13 +166,19 @@ sub all {
 sub _get {
     my $self = shift;
 
-    scalar(@_) == 2
-        or croak '_get takes type and search string as parameters';
+    ( scalar(@_) == 2
+      or ( scalar(@_) == 3 and ( !defined $_[2] or ref $_[2] eq 'HASH' ) ) )
+        or croak '_get takes type and search string as parameters (and an optional params hash)';
 
-    my $type = shift;
-    my $arg  = shift;
+    my $type   = shift;
+    my $arg    = shift;
+    my $params = shift;
 
-    my $response = $self->fetch("$type/$arg");
+    my $fields_filter = $self->_read_fields( $params );
+
+    my $response = $self->fetch(
+        sprintf("%s/%s%s", $type ,$arg, $fields_filter)
+    );
     ref $response eq 'HASH'
         or croak sprintf( 'Failed to fetch %s (%s)', ucfirst($type), $arg );
 
@@ -187,6 +186,27 @@ sub _get {
     return $class->new_from_request($response, $self);
 }
 
+sub _read_fields {
+    my $self   = shift;
+    my $params = shift;
+    $params or return '';
+
+    my $fields = delete $params->{fields};
+
+    if ( ref $fields eq 'ARRAY' ) {
+        grep { ref $_ } @$fields
+            and croak "fields array should not contain any refs.";
+
+        return sprintf( "?fields=%s", join q{,} => @$fields );
+
+    } elsif ( !ref $fields ) {
+
+        return "?fields=$fields";
+    }
+
+    croak "invalid param: fields";
+}
+
 sub _search {
     my $self   = shift;
     my $type   = shift;
@@ -222,7 +242,7 @@ sub _get_or_search {
         return $self->_search( $type, $arg, $params );
 
     defined $arg and ! ref($arg)
-        and return $self->_get($type, $arg);
+        and return $self->_get($type, $arg, $params);
 
     croak "$type: invalid args (takes scalar value or search parameters hashref)";
 }
@@ -316,7 +336,7 @@ MetaCPAN::Client - A comprehensive, DWIM-featured client to the MetaCPAN API
 
 =head1 VERSION
 
-version 1.008001
+version 1.013000
 
 =head1 SYNOPSIS
 
@@ -413,10 +433,14 @@ Return a L<MetaCPAN::Client::File> object.
 
 =head2 favorite
 
+    my $favorite = $mcpan->favorite({ distribution => 'Moose' });
+
 Return a L<MetaCPAN::Client::Favorite> object.
 
 =head2 rating
 
+    my $rating = $mcpan->rating({ distribution => 'Moose' });
+
 Return a L<MetaCPAN::Client::Rating> object.
 
 =head2 release
@@ -432,6 +456,12 @@ Return a L<MetaCPAN::Client::Release> object on a simple search (release name),
 or a L<MetaCPAN::Client::ResultSet> object propagated with
 L<MetaCPAN::Client::Release> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
+=head2 mirror
+
+    my $mirror = $mcpan->mirror('kr.freebsd.org');
+
+Returns a L<MetaCPAN::Client::Mirror> object.
+
 =head2 reverse_dependencies
 
     my $deps = $mcpan->reverse_dependencies('ElasticSearch');
@@ -462,14 +492,46 @@ formats (html, plain, x_pod & x_markdown).
 
 =head2 all
 
-Retrieve all matches for authors/modules/distributions or releases.
+Retrieve all matches for authors/modules/distributions/favorites or releases.
 
     my $all_releases = $mcpan->all('releases')
 
+When called with a second parameter containing a hash ref,
+will support the following keys:
+
+=head3 fields
+
+See SEARCH PARAMS.
+
+   my $all_releases = $mcpan->all('releases', { fields => [...] })
+
+=head3 es_filter
+
+Pass a raw ElasticSearch filter structure to reduce the number
+of elements returned by the query.
+
+    my $some_releases = $mcpan->all('releases', { es_filter => {...} })
+
 =head2 BUILDARGS
 
 Internal construction wrapper. Do not use.
 
+=head1 SEARCH PARAMS
+
+Most searches take params as an optional hash-ref argument.
+these params will be passed to the search action.
+
+In non-scrolled searches, 'fields' filter is the only supported
+parameter ATM.
+
+=head2 fields
+
+Filter the fields to reduce the amount of data pulled from MetaCPAN.
+can be passed as a csv list or an array ref.
+
+    my $module = $mcpan->module('Moose', { fields => "version,author" });
+    my $module = $mcpan->module('Moose', { fields => [qw/version author/] });
+
 =head1 SEARCH SPEC
 
 The hash-based search spec is common to many searches. It is quite
@@ -2,11 +2,11 @@ use 5.006;
 use strict;
 use warnings;
 
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.051
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.052
 
 use Test::More;
 
-plan tests => 12 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+plan tests => 13 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
 
 my @module_files = (
     'MetaCPAN/Client.pm',
@@ -14,6 +14,7 @@ my @module_files = (
     'MetaCPAN/Client/Distribution.pm',
     'MetaCPAN/Client/Favorite.pm',
     'MetaCPAN/Client/File.pm',
+    'MetaCPAN/Client/Mirror.pm',
     'MetaCPAN/Client/Module.pm',
     'MetaCPAN/Client/Pod.pm',
     'MetaCPAN/Client/Rating.pm',