jeroen-g / explorer Goto Github PK
View Code? Open in Web Editor NEWπΊοΈ Next-gen Elasticsearch driver for Laravel Scout.
Home Page: https://jeroen-g.github.io/Explorer/
License: MIT License
πΊοΈ Next-gen Elasticsearch driver for Laravel Scout.
Home Page: https://jeroen-g.github.io/Explorer/
License: MIT License
The demo app here is using elasticsearch 7.9.3
, but it isn't clear if 8.0.x
is supported π€ it is.
I'm in the process of switching to this package, but there is an elasticsearch feature I've been using, but I can't find a way to set it using this package.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-refresh.html
I would like to be able to set refresh to wait_for. We use it in tests to see if our filters and score boosts yield the expected results from elasticsearch. Is there a way to set the refresh parameter?
I think this PR might be related, but the author closed it. #89
For example:
Post::search('lorem')->must(new Matching('title', 'ipsum'))->dump()->get();
Hi there
i am using elasticsearch on docker.
here is my docker-compose.yml
other containers ...
elastic01:
image: elasticsearch:7.13.4
container_name: elastic01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./docker/elasticsearch:/usr/share/elasticsearch/data
ports:
- 9201:9200
networks:
- app
- elastic
i have configured laravel scout and this package as just documentation
and i have imported model's data by running
php artisan scout:import \App\Models\Post
but when i try to search in models or run php artisan elastic:create
i get this error
Elasticsearch\Common\Exceptions\NoNodesAvailableException
No alive nodes found in your cluster
at vendor/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/StaticNoPingConnectionPool.php:64
60β return $connection;
61β }
62β }
63β
β 64β throw new NoNodesAvailableException("No alive nodes found in your cluster");
65β }
66β
67β public function scheduleCheck(): void
68β {
+26 vendor frames
27 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
ERROR: 1
i searched this error in google and i realized that i have to disable ssl verification . how can i do that?
Jag fick ett mail frΓ₯n Zettle idag:
A new version V3 of the Inventory API is released, which replaces the previous versions. Previous versions are now deprecated but will remain available until 31 May, 2023.
En lΓ€nk till uppgraderingsguiden: https://developer.zettle.com/docs/api/inventory-v3/inventory-api-migration-guide
Hi,
Can have option to use basic auth in request?
In elasticsearch ClientBuilder, there is a function setBasicAuthentication which accepts username and password.
Hello @Jeroen-G!
Could you please make a new release, since there are quite a lot of new code in the master branch.
Range should be allowed to start from 0
Error:
Expected a non-empty value. Got: "0"
How to reproduce:
new Range($field, [
'gte' => 0,
'lte' => 5
]);
Removing Assert::notEmpty($value);
from Range.php on line 38 resolves the issue and works as intended.
Versions:
Explorer 3.3.1
Elasticsearch 8.5.0
Hi, I'm using you package, thanks a lot.
I have a App\Models\Questions, with the following code:
namespace App\Models;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use JeroenG\Explorer\Application\Explored;
use Laravel\Scout\Searchable;
class Question extends Model implements Explored
{
use HasFactory, Searchable;
/**
* Get the name of the index associated with the model.
*
* @return string
*/
public function searchableAs()
{
return 'questions_index';
}
public function mappableAs(): array
{
return [
'external_uid',
'title',
'index_rubrique',
'index_analyse',
'question_texte',
'reponse_texte',
'question_parution_jo',
'reponse_parution_jo',
];
}
}
I made a php artisan scout:import "App\Models\Question"
and it seems to go well:
Imported [App\Models\Question] models up to ID: 500
Imported [App\Models\Question] models up to ID: 1000
Imported [App\Models\Question] models up to ID: 1500
Imported [App\Models\Question] models up to ID: 2000
Imported [App\Models\Question] models up to ID: 2500
Imported [App\Models\Question] models up to ID: 3000
Imported [App\Models\Question] models up to ID: 3500
Imported [App\Models\Question] models up to ID: 4000
Imported [App\Models\Question] models up to ID: 4500
Imported [App\Models\Question] models up to ID: 5000
(...)
Imported [App\Models\Question] models up to ID: 92729
All [App\Models\Question] records have been imported.
But, I can't see anything in my elastic server (I am using Elastron to browse, and I can't see my questions_index
).
Moreover, when I execute php artisan elastic:search "App\Models\Question" ministre
:
Starting to search for ministre
In Results.php line 41:
Undefined array key "hits"
Do you know what happen, or what I did wrong?
Thanks for your help.
Edit:
Here is my config/explorer.php:
declare(strict_types=1);
return [
/*
* There are different options for the connection. Since Explorer uses the Elasticsearch PHP SDK
* under the hood, all the host configuration options of the SDK are applicable here. See
* https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/configuration.html
*/
'connection' => [
'host' => env('ELASTICSEARCH_HOST', 'localhost'),
'port' => env('ELASTICSEARCH_PORT', '9200'),
'scheme' => env('ELASTICSEARCH_SCHEME', 'https'),
'auth' => [
'username' => env('ELASTICSEARCH_USER', ''),
'password' => env('ELASTICSEARCH_PASS', ''),
],
],
/**
* An index may be defined on an Eloquent model or inline below. A more in depth explanation
* of the mapping possibilities can be found in the documentation of Explorer's repository.
*/
'indexes' => [
// \App\Models\Post::class
\App\Models\Question::class,
],
/**
* You may opt to keep the old indices after the alias is pointed to a new index.
* A model is only using index aliases if it implements the Aliased interface.
*/
'prune_old_aliases' => true,
];
The new default laravel/scout installation is using "^9.1" version. But Explorer still requiring ^8.0.
When you guys upgrade?
When I deploy my project by pushing to GitHub, I wouldn't want to include credentials and connection information in config/explorer.php
as in the examples. Can this use environment variables like other data sources, such as Redis (uses REDIS_URL
) ? Where can I find the correct names for those?
It's not done yet (#44). There is a breaking change in v9.0 to implement 2 new methods createIndex($name, array $options = []);
and deleteIndex($name);
in Engines/Engine.php
are you able to implement in JeroenG\Explorer\Infrastructure\Scout\ElasticEngine ? otherwise, it will not work.
change log in v9.0
laravel/scout@db9e7b2
error was:
{
"message": "Class JeroenG\\Explorer\\Infrastructure\\Scout\\ElasticEngine contains 3 abstract methods and must therefore be declared abstract or implement the remaining methods (Laravel\\Scout\\Engines\\Engine::lazyMap, Laravel\\Scout\\Engines\\Engine::createIndex, Laravel\\Scout\\Engines\\Engine::deleteIndex)",
"exception": "Symfony\\Component\\ErrorHandler\\Error\\FatalError",
"file": "~\\vendor\\jeroen-g\\explorer\\src\\Infrastructure\\Scout\\ElasticEngine.php",
"line": 16,
"trace": []
}
I have a single index with my Product model implementing the shouldBeSearchable() method.
When I save a product I get this exception:
Elasticsearch\Common\Exceptions\Missing404Exception
{"_index":"products","_type":"_doc","_id":"6","_version":1,"result":"not_found","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":3,"_primary_term":1}
I can solve this by not implementing the shouldBeSearchable() and do the query's like:
Product::Search($this->search)
->filter(new Term('published', true))
.. but it would be nice if the other method worked as well
Hello, I'm trying to map a model but every time I index the changes nothing has been used.
Made sure to clear everything from ES when testing it.
Commands that i tried:
php artisan elastic:update
and
php artisan scout:import "App\Models\AgencyOffer"
Tried to map it both from the config file explorer.php
and also with mappableAs neither worked.
Here is how my mapping looks like:
'indexes' => [
'agency_offers_index' => [
'properties' => [
'id' => 'keyword',
'agency_id' => 'keyword',
'agency_broker_id' => 'keyword',
'agency_client_id' => 'keyword',
'name' => 'object',
'description' => 'object',
'ref_code' => 'long',
'deal_type' => 'long',
'status' => 'long',
'property_main_type_id' => 'long',
'property_sub_type_id' => 'long',
'property_source_id' => 'long',
'property_location_domain_id' => 'long',
'property_location_domain_city_id' => 'long',
'property_location_domain_sub_city_id' => 'long',
'property_location_domain_city_street_id' => 'long',
'address' => 'text',
'coordinates' => 'text',
'old_price' => 'long',
'price' => 'long',
'price_with_commission' => 'long',
'property_currency_id' => 'long',
'exclusive' => 'long',
'top' => 'long',
'nocommision' => 'long',
'ask_price' => 'long',
'youtube_link' => 'text',
'bird_eye_360' => 'text',
'property_portal_ids' => 'long',
'created_at' => 'date',
'updated_at' => 'date',
'deleted' => 'long',
'deleted_at' => 'date',
'restored_at' => 'date',
'coordinates_full' => 'text'
]
]
]
Versions:
Tried with both 3.2.1 and 3.3.0
Laravel 9.37
PHP 8.1.10
Elasticsearch 7.9.3
Probably best to add constructor which accept many arguments with func_get_args?
is there a special way to continue feeding the index on the model events for saved and updated? It doesn't appear that the package creates a new doc or updates the doc after model manipulation.
I am not sure if I have something misconfigured or not.
Hi, When i use Laravel Scout option "queue" => 'true' i have a error in my queue docker container No alive nodes found in your cluster, but everything work without queue.
I enter the docker-container and ping + Curl elasticsearch host, Elastic works and all ok. But i don't understand problem.....
If i manually create the index structure in che config.explorer.php file, when actually creating the index in elastic search the
"type": "nested"
part gets skipped and does not let me have the correct index mapping and content.
Is this a bug or am I missing something in the manual index mapping configuration?
Great package. I think you should have the the Elasticsearch query types and aggregations published to a directory under the app folder. This way it can be customized and you don't have to submit a PR to add a query type or aggregation
App/Explorer
-> Queries
-> Terms.php
-> etc....
-> Aggregations
-> Terms.php
-> etc....
php artisan vendor:publish --tag=explorer.queries
php artisan vendor:publish --tag=explorer.aggs
I am going to see what I can come up with and give you a PR.
I want pagination in my search result as below:
$posts = Post::search('my post')->paginate(20);
Do Explorer has implemented scout paginate method . How can i achieve pagination ?
Hi,
I hope you are doing well. I like your package however I am not able to search based on relationship. Could you please help me out here? I have a simple app which you can clone from here.
I am having two indexes. One for model Post another for Category, really easy. What I am trying to do in PostController index method is to just search post based on category which should be nested.
I have added the Post model to explorer.php config as written in docs and added this code to Post.php model:
public function mappableAs(): array
{
return [
'id' => 'keyword',
'title' => 'text',
'summary' => 'text',
'category' => [
'id' => 'keyword',
'title' => 'text'
]
];
}
The error I am getting is pretty long:
{"error":{"root_cause":[{"type":"query_shard_exception","reason":"failed to create query: [nested] nested object under path [category] is not of nested type","index_uuid":"oHabVRbcTxa9HJ6mv_qXAw","index":"posts_index"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"posts_index","node":"PhZDSsmrRN62Fy5wzg_Ayg","reason":{"type":"query_shard_exception","reason":"failed to create query: [nested] nested object under path [category] is not of nested type","index_uuid":"oHabVRbcTxa9HJ6mv_qXAw","index":"posts_index","caused_by":{"type":"illegal_state_exception","reason":"[nested] nested object under path [category] is not of nested type"}}}]},"status":400}
It seems as the category is not nested type but I followed your docs.
So I tried to use only the explorer.php array but when I use this config:
'indexes' => [
'posts' => [
'properties' => [
'id' => 'keyword',
'title' => 'text',
'created_at' => 'date',
'category' => 'nested',
],
],
],
I am getting following error when running the php artisan elastic:update command:
Any help is appreciated!
Class: JeroenG\Explorer\Domain\Syntax\Nested
It seems that the "orderBy" function does not support sorting on fields of type geo_point.
The bellow function call will return every index entries within a distance of $location['distance']
of the given location coordinate.
$searcher->must(new GeoDistance('locations', [ (float) $location['lat'], (float) $location['lon']], $location['distance'] ?? '200km'));
When trying to apply a orderBy('locations')
, I get this error:
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"can't sort on geo_point field without using specific sorting feature, like geo_distance"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"offers","node":"66qPfbXCQ7Kch-EAzjHhOA","reason":{"type":"illegal_argument_exception","reason":"can't sort on geo_point field without using specific sorting feature, like geo_distance"}}],"caused_by":{"type":"illegal_argument_exception","reason":"can't sort on geo_point field without using specific sorting feature, like geo_distance","caused_by":{"type":"illegal_argument_exception","reason":"can't sort on geo_point field without using specific sorting feature, like geo_distance"}}},"status":400}
I have tried a few things but none of my attempts seem to work. Is this even out of the box supported?
What the ElasticSearch query should look like:
GET offers/_search
{
"size": 1,
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "100km",
"locations": {
"lat": -89.440879,
"lon": 124.327279
}
}
}
}
},
"sort": [
{
"_geo_distance": {
"locations": {
"lat": -89.440879,
"lon": 124.327279
}
}
}
]
}
Thanks!
Hello, after running sail php artisan elastic:create
i'm getting this error
{"error":{"root_cause":[{"type":"parse_exception","reason":"key [settings] must be an object"}],"type":"parse_exception","reason":"key [settings] must be an object"},"status":400}
my explorer.php file content is:
<?php
declare(strict_types=1);
return [
/*
* There are different options for the connection. Since Explorer uses the Elasticsearch PHP SDK
* under the hood, all the host configuration options of the SDK are applicable here. See
* https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/configuration.html
*/
'connection' => [
'host' => 'es01',
'port' => '9200',
'scheme' => 'http',
],
/**
* An index may be defined on an Eloquent model or inline below. A more in depth explanation
* of the mapping possibilities can be found in the documentation of Explorer's repository.
*/
'indexes' => [
\Modules\Contract\Entities\Contract::class,
\Modules\Content\Entities\Blog::class
],
/**
* You may opt to keep the old indices after the alias is pointed to a new index.
* A model is only using index aliases if it implements the Aliased interface.
*/
'prune_old_aliases' => true,
];
and i have implemented Explorer "mappableAs" for both my models
there is no console command create, delete in the package
Upgrade to laravel 9 is not possible. Composer.json in master branch looks good, but composer.json in latest release have only laravel 7., 8. versions
composer update result:
Root composer.json requires jeroen-g/explorer ^2.4 -> satisfiable by jeroen-g/explorer[v2.4.0, 2.4.1, v2.5.0, 2.5.1].
- Conclusion: don't install laravel/framework v9.0.0-beta.2 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.0-beta.3 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.0-beta.4 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.0-beta.5 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.0 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.1 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.2 (conflict analysis result)
- Conclusion: don't install laravel/framework v9.0.0-beta.1 (conflict analysis result)
- jeroen-g/explorer[v2.4.0, ..., 2.5.1] require illuminate/support ~7|~8 -> satisfiable by illuminate/support[v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev].
- Only one of these can be installed: illuminate/support[v5.6.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev, v9.0.0-beta.1, ..., 9.x-dev], laravel/framework[v9.0.0-beta.1, ..., 9.x-dev]. laravel/framework replaces illuminate/support and thus cannot coexist with it.
- Root composer.json requires laravel/framework ^9.0 -> satisfiable by laravel/framework[v9.0.0-beta.1, ..., 9.x-dev].
I placed additional parameters in the elasticsearch index. The index has been created, everything is fine. But when I fetch the data via get() or paginate(), only the attributes of the model are returned to me. And I really checked - in addition, a regular sql query is executed. But I don't want to fetch data from the database. I want to fetch data from ElasticSearch index
As a result of #31 we can refactor compound queries to support other queries then BoolQuery.
After Composer Update =>
error: βJeroenG\\Explorer\\Infrastructure\\Elastic\\ElasticIndexAdapter::__construct(): Argument #1 ($clientFactory) must be of type JeroenG\\Explorer\\Infrastructure\\Elastic\\ElasticClientFactory, Elasticsearch\\Client givenβ
I tried to get an example working in the demo application for Explorer: Jeroen-G/explorer-demo#4
It seems that there is a bug if I look at the query it runs and what ES expects according to https://www.elastic.co/guide/en/elasticsearch/reference/7.13/query-dsl-nested-query.html#nested-query-ex-query
I think Nested should be refactored to replace the overall bool query instead of being a child of it.
Originally posted by @Jeroen-G in #59 (comment)
Hi there,
I have created two indexes using php artisan elastic:create
. Index definitions are in config/explorer.php
. Then I needed to add third index definition so I added it at the beginning of explorer.php
config which worked with elastic:create
(indeed it did crash but the first index was created).
Now I'm wondering if life wouldn't be easier with added optional argument like elastic:create <index_name>
or elastic:delete <index_name>
. We could create/delete exact indexes(?) as they are configured in explorer.php
.
Thanks.
Package version jeroen-g/explorer v2.4.0
PHP 7.4 / 8.0
Hi there
I want to add custom query parameter in search function, as documented here https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
such as track_total_hits
because it only return maximum 10000 record, I have to manually add this paramter to query builder.
But there is no place to add in the ScoutSearchCommandBuilder
Can you add some custom Params after this
$query = new Query();
$query->setFields($this->fields);
$query->setSort($this->sort);
$query->setLimit($this->limit);
$query->setOffset($this->offset);
like
+ $query->setParams($this->params);
Regards
Jack
Hi. I have read documenation and seen support nested query.
$posts = Post::search('my post') ->must(new Nested('author', new Matching('author.name', 'Jeroen'))) ->get();
I have Index
'route' => [ 'loading' => 'nested', 'unloading' => 'nested' ],
And when i use query
return $query->must(new Nested('route', new Wildcard('route.unloading.point.zipcode', '*'.request('zipcode_to').'*')));
I have Elastic Error "reason":"[nested] failed to find nested object under path ['route]
I checked my index and it's ok.
Is it possible to make use of the highlight functionallity with this package? https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html
hi
i cant create data
Exception
Please install the Algolia client: algolia/algoliasearch-client-php.
at vendor/laravel/scout/src/EngineManager.php:80
76β if (class_exists('AlgoliaSearch\Client')) {
77β throw new Exception('Please upgrade your Algolia client to version: ^2.2.');
78β }
79β
β 80β throw new Exception('Please install the Algolia client: algolia/algoliasearch-client-php.');
81β }
82β
83β /**
84β * Set the default Algolia configuration headers.
There are a lot of new features in the master branch, would it be possible to make a new release?
How could I send a raw query ?
Model::search(raw_query_formatted_in_JSON)
ELK 7.9.3 / 8.3.2
My arabic analyzer doen't work unless I implement the Aliased
interface
My Model code
class Word extends EloquentModel implements Explored, IndexSettings, Aliased
{
// prev
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'name' => $this->name,
];
}
public function mappableAs(): array
{
return [
'id' => 'long',
'name' => [
'type' => 'text',
'analyzer' => 'arabic',
],
];
}
public function indexSettings(): array
{
// return [
// "analysis" => [
// "filter" => [
// "arabic_stemmer" => [
// "type" => "stemmer",
// "language" => "arabic",
// ],
// ],
// "analyzer" => [
// "rebuilt_arabic" => [
// "tokenizer" => "standard",
// "filter" => [
// "lowercase",
// "decimal_digit",
// "arabic_stemmer",
// "arabic_normalization",
// ],
// ],
// ],
// ],
// ];
$analyzer = new StandardAnalyzer('arabic');
$analyzer->setFilters(['lowercase', 'decimal_digit', 'arabic_normalization']);
return (new Analysis())
->addAnalyzer($analyzer)
->build();
// $arabicNormalizerFilter = new ArabicNormalizerFilter();
//
// $arabicAnalyzer = new StandardAnalyzer('custom_arabic');
// $arabicAnalyzer->setFilters(['lowercase', $arabicNormalizerFilter]);
//
// return (new Analysis())
// ->addAnalyzer($arabicAnalyzer)
// ->addFilter($arabicNormalizerFilter)
// ->build();
// $synonymFilter = new SynonymFilter();
// $synonymFilter->setSynonyms(['mona lisa => leonardo']);
//
// $synonymAnalyzer = new StandardAnalyzer('synonym');
// $synonymAnalyzer->setFilters(['lowercase', $synonymFilter]);
//
// return (new Analysis())
// ->addAnalyzer($synonymAnalyzer)
// ->addFilter($synonymFilter)
// ->build();
}
}
I checked the php artisan elastic:update
command and found that the method updateIndex
in ElasticUpdate
class is actually checking for alias to do mapping and this part is totally missing in the documentation.
private function updateIndex(
IndexConfigurationInterface $indexConfiguration,
IndexAdapterInterface $indexAdapter
): void {
if ($indexConfiguration->isAliased()) {
$indexAdapter->createNewWriteIndex($indexConfiguration);
}
if (!is_null($indexConfiguration->getModel())) {
$output = Artisan::call('scout:import', ["model" => $indexConfiguration->getModel()], $this->output);
if ($output !== 0) {
$this->error(sprintf("Import of model %s failed", $indexConfiguration->getModel()));
return;
}
}
$indexAdapter->pointToAlias($indexConfiguration);
}
It seems global search doesn't work in "Laravel Nova" with Explorer and Scout.
The error is like this.
Method Illuminate\Database\Eloquent\Collection::cursor does not exists.
Laravel Version: 8.61.0
When I change cursor method to lazy in ElasticEngine.php line 160, it works as expected. According to the documentation Eager load relationships are not working with cursors. So the documentation suggest lazy method instead of cursor.
Here is the documentation what says about cursors
Since the cursor method only ever holds a single Eloquent model in memory at a time, it cannot eager load relationships. If you need to eager load relationships, consider using the lazy method instead.
public function lazyMap(Builder $builder, $results, $model): LazyCollection
{
Assert::isInstanceOf($results, Results::class);
if ($results->count() === 0) {
return LazyCollection::make($model->newCollection());
}
$objectIds = $this->mapIds($results)->all();
$objectIdPositions = array_flip($objectIds);
return $model->getScoutModelsByIds(
$builder,
$objectIds
)->cursor()->filter(function ($model) use ($objectIds) {
return in_array($model->getScoutKey(), $objectIds, false);
})->sortBy(function ($model) use ($objectIdPositions) {
return $objectIdPositions[$model->getScoutKey()];
})->values();
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.