/*! For license information please see f0c930b7.2e9e07b8.js.LICENSE.txt */
(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4409],{4137:function(e,t,n){"use strict";n.d(t,{Zo:function(){return c},kt:function(){return f}});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):u(u({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),m=s(n),f=o,g=m["".concat(l,".").concat(f)]||m[f]||p[f]||a;return n?r.createElement(g,u(u({ref:t},c),{},{components:n})):r.createElement(g,u({ref:t},c))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,u=new Array(a);u[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i.mdxType="string"==typeof e?e:o,u[1]=i;for(var s=2;s<a;s++)u[s]=n[s];return r.createElement.apply(null,u)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},6261:function(e,t,n){"use strict";var r=n(7294),o=n(4184),a=n.n(o);t.Z=function(e){var t=e.children,n=e.classNames,o=e.fill,u=e.icon,i=e.type,l=null;switch(i){case"danger":l="alert-triangle";break;case"success":l="check-circle";break;case"warning":l="alert-triangle";break;default:l="info"}return r.createElement("div",{className:a()(n,"alert","alert--"+i,{"alert--fill":o,"alert--icon":!1!==u}),role:"alert"},!1!==u&&r.createElement("i",{className:a()("feather","icon-"+(u||l))}),t)}},5867:function(e,t,n){"use strict";n.r(t),n.d(t,{frontMatter:function(){return l},contentTitle:function(){return s},metadata:function(){return c},toc:function(){return p},default:function(){return f}});var r=n(7462),o=n(3366),a=(n(7294),n(4137)),u=n(6261),i=["components"],l={title:"Java",sidebar_label:"java",description:"Pinot Java Client",draft:!0},s=void 0,c={unversionedId:"user-guide/clients/java",id:"user-guide/clients/java",isDocsHomePage:!1,title:"Java",description:"Pinot Java Client",source:"@site/docs/user-guide/clients/java.md",sourceDirName:"user-guide/clients",slug:"/user-guide/clients/java",permalink:"/docs/user-guide/clients/java",editUrl:"https://github.com/apache/pinot/edit/master/website/docs/user-guide/clients/java.md",version:"current",frontMatter:{title:"Java",sidebar_label:"java",description:"Pinot Java Client",draft:!0}},p=[],m={toc:p};function f(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.kt)("wrapper",(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The java client can be found in pinot-clients/pinot-java-client. Here's an example of how to use the pinot-java-client to query Pinot."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'import org.apache.pinot.client.Connection;\nimport org.apache.pinot.client.ConnectionFactory;\nimport org.apache.pinot.client.Request;\nimport org.apache.pinot.client.ResultSetGroup;\nimport org.apache.pinot.client.ResultSet;\n\n/**\n * Demonstrates the use of the pinot-client to query Pinot from Java\n */\npublic class PinotClientExample {\n\n  public static void main(String[] args) {\n\n    // pinot connection\n    String zkUrl = "localhost:2181";\n    String pinotClusterName = "PinotCluster";\n    Connection pinotConnection = ConnectionFactory.fromZookeeper(zkUrl + "/" + pinotClusterName);\n\n    String query = "SELECT COUNT(*) FROM myTable GROUP BY foo";\n\n    // set queryType=sql for querying the sql endpoint\n    Request pinotClientRequest = new Request("sql", query);\n    ResultSetGroup pinotResultSetGroup = pinotConnection.execute(pinotClientRequest);\n    ResultSet resultTableResultSet = pinotResultSetGroup.getResultSet(0);\n\n    int numRows = resultTableResultSet.getRowCount();\n    int numColumns = resultTableResultSet.getColumnCount();\n    String columnValue = resultTableResultSet.getString(0, 1);\n    String columnName = resultTableResultSet.getColumnName(1);\n\n    System.out.println("ColumnName: " + columnName + ", ColumnValue: " + columnValue);\n  }\n}\n')),(0,a.kt)("p",null,"Connections to Pinot are created using the ConnectionFactory class' utility methods to create connections to a Pinot cluster given a Zookeeper URL, a Java Properties object or a list of broker addresses to connect to."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'Connection connection = ConnectionFactory.fromZookeeper\n  ("some-zookeeper-server:2191/zookeeperPath");\n\nConnection connection = ConnectionFactory.fromProperties("demo.properties");\n\nConnection connection = ConnectionFactory.fromHostList\n  ("some-server:1234", "some-other-server:1234", ...);\n')),(0,a.kt)("p",null,"Queries can be sent directly to the Pinot cluster using the ",(0,a.kt)("inlineCode",{parentName:"p"},"Connection.execute(org.apache.pinot.client.Request)")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Connection.executeAsync(org.apache.pinot.client.Request)")," methods of Connection:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'ResultSetGroup resultSetGroup =\n  connection.execute(new Request("sql", "select * from foo..."));\n// OR\nFuture<ResultSetGroup> futureResultSetGroup =\n  connection.executeAsync(new Request("sql", "select * from foo..."));\n')),(0,a.kt)("p",null,"Queries can also use a ",(0,a.kt)("inlineCode",{parentName:"p"},"PreparedStatement")," to escape query parameters:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'PreparedStatement statement =\n    connection.prepareStatement(new Request("sql", "select * from foo where a = ?"));\nstatement.setString(1, "bar");\n\nResultSetGroup resultSetGroup = statement.execute();\n// OR\nFuture<ResultSetGroup> futureResultSetGroup = statement.executeAsync();\n')),(0,a.kt)("p",null,"Results can be obtained with the various get methods in the first ResultSet, obtained through the getResultSet(int) method:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'Request request = new Request("sql", "select foo, bar from baz where quux = \'quuux\'");\nResultSetGroup resultSetGroup = connection.execute(request);\nResultSet resultTableResultSet = pinotResultSetGroup.getResultSet(0);\n\nfor (int i = 0; i < resultSet.getRowCount(); ++i) {\n  System.out.println("foo: " + resultSet.getString(i, 0));\n  System.out.println("bar: " + resultSet.getInt(i, 1));\n}\n')),(0,a.kt)(u.Z,{type:"info",mdxType:"Alert"}," The examples for the sections below this note, are for querying the PQL endpoint, which is deprecated and will be deleted soon. For more information about the 2 endpoints, visit [Querying Pinot](/docs/user-guide/query-pinot)."),(0,a.kt)("p",null,"If queryFormat pql is used in the Request,  there are some differences in how the results can be accessed, depending on the query.\nIn the case of aggregation, each aggregation function is within its own ResultSet. A query with multiple aggregation function will return one result set per aggregation function, as they are computed in parallel."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'ResultSetGroup resultSetGroup =\n    connection.execute(new Request("pql", "select max(foo), min(foo) from bar"));\n\nSystem.out.println("Number of result groups:" +\n    resultSetGroup.getResultSetCount(); // 2, min(foo) and max(foo)\nResultSet resultSetMax = resultSetGroup.getResultSet(0);\nSystem.out.println("Max foo: " + resultSetMax.getInt(0));\nResultSet resultSetMin = resultSetGroup.getResultSet(1);\nSystem.out.println("Min foo: " + resultSetMin.getInt(0));\n')),(0,a.kt)("p",null,"In case of aggregation group by, there will be as many ResultSets as the number of aggregations, each of which will contain multiple results grouped by a group key."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'ResultSetGroup resultSetGroup =\n    connection.execute(\n        new Request("pql", "select min(foo), max(foo) from bar group by baz"));\n\nSystem.out.println("Number of result groups:" +\n    resultSetGroup.getResultSetCount(); // 2, min(foo) and max(foo)\n\nResultSet minResultSet = resultSetGroup.getResultSet(0);\nfor(int i = 0; i < minResultSet.length(); ++i) {\n    System.out.println("Minimum foo for " + minResultSet.getGroupKeyString(i, 1) +\n        ": " + minResultSet.getInt(i));\n}\n\nResultSet maxResultSet = resultSetGroup.getResultSet(1);\nfor(int i = 0; i < maxResultSet.length(); ++i) {\n    System.out.println("Maximum foo for " + maxResultSet.getGroupKeyString(i, 1) +\n        ": " + maxResultSet.getInt(i));\n}\n')))}f.isMDXComponent=!0},4184:function(e,t){var n;!function(){"use strict";var r={}.hasOwnProperty;function o(){for(var e=[],t=0;t<arguments.length;t++){var n=arguments[t];if(n){var a=typeof n;if("string"===a||"number"===a)e.push(n);else if(Array.isArray(n)){if(n.length){var u=o.apply(null,n);u&&e.push(u)}}else if("object"===a)if(n.toString===Object.prototype.toString)for(var i in n)r.call(n,i)&&n[i]&&e.push(i);else e.push(n.toString())}}return e.join(" ")}e.exports?(o.default=o,e.exports=o):void 0===(n=function(){return o}.apply(t,[]))||(e.exports=n)}()}}]);