مقدمة
في المقالة السابقة ، تم دمج Springboot و MyBatis و Druid و Pagehelper وتم تنفيذ عمليات مصادر بيانات متعددة. تقدم هذه المقالة بشكل أساسي وتستخدم Elastisearch ، وهو محرك البحث الأكثر شعبية ، ويستخدمها مع Springboot.
مقدمة إلى Elasticsearch
Elasticsearch هو خادم بحث يعتمد على Lucene. إنه يلف بالفعل لورين ويوفر واجهة تشغيل واجهة برمجة تطبيقات REST. Elasticsearch هو محرك بحث وتحليل النص الكامل قابل للتطوير للغاية والذي يمكن استخدامه لتخزين البيانات الكبيرة والبحث وتحليلها بسرعة.
الميزات الرئيسية لـ Elasticsearch: توافر موزعة ، عالية ، الكتابة غير المتزامنة ، متعددة API ، موجهة نحو المستندات.
المفاهيم الأساسية Elasticsearch: بالقرب من الوقت الفعلي ، المجموعة ، العقدة (حفظ البيانات) ، الفهرس ، Shard (شظايا مؤشر التقطيع) ، النسخ المتماثلة (يمكن أن تضع التقطيع نسخ متماثلة متعددة). يمكن أن تخزن بسرعة والبحث وتحليل كميات هائلة من البيانات.
حالات استخدام Elasticsearch: Wikipedia ، Stack Overflow ، Github ، إلخ.
Springboot يدمج Elasticsearch
قبل استخدام Springboot لدمج Elasticsearch ، يجب أن نفهم العلاقة بينهما.
| نسخة التمهيد الربيع (x) | إصدار بيانات الربيع Elasticsearch (Y) | إصدار Elasticsearch (Z) |
|---|---|---|
| x <= 1.3.5 | y <= 1.3.4 | z <= 1.7.2* |
| x> = 1.4.x | 2.0.0 <= y <5.0.0 ** | 2.0.0 <= z <5.0.0 ** |
إصدار SpringBoot الذي نستخدمه هنا هو 1.5.9 ، وإصدار Elasticsearch هو 2.3.5.
باستخدام SpringBoot لدمج Elasticsearch ، يتم تغليفه عمومًا باستخدام SpringData ، ثم ترث واجهة طبقة DAO فئة ElasticsearchRepository. ينفذ هذا الفئة العديد من الطرق ، مثل طريقة CRUD شائعة الاستخدام.
استخدام SpringData
أولاً ، قم بإجراء الاستعدادات ذات الصلة قبل الاستخدام.
تكوين Maven كما يلي:
<Rependency> <roupeD> org.springframework.boot </groupId> <intifactid> Spring-Boot-Starter-Web </shintifactid> <sored> 1.5.9 <StifactId> Spring-Boot-Starter-Data-Elasticsearch </artifactId> <الإصدار> 1.5.9
تكوين application.properties
spring.data.elasticsearch.repositories.endabled = truespring.data.elasticsearch.cluster-nodes = 127.0.0.1/: 9300
ملاحظة: 9300 هو منفذ عميل Java. 9200 هي واجهة تدعم HTTP RESTful.
المزيد من التكوينات:
spring.data.elasticsearch.cluster-name elasticsearch اسم الكتلة. (افتراضي: Elasticsearch)
spring.data.elasticsearch.cluster-nodes قائمة عناوين عقدة الكتلة ، مفصولة بفواصل. إذا لم يتم تحديدها ، ابدأ عقدة العميل.
spring.data.elasticsearch.propertie يستخدم لتكوين خصائص إضافية للعميل.
Spring.Data.Elasticsearch.Repositories.Enabled تمكين مستودع Elasticsearch. (افتراضي: صحيح.)
كتابة الكود
فئة الكيان
document (indexName = "userIndex" ، type = "user") يقوم مستخدم الفئة العامة بتنفيذ serializable { / ** * * / private static Final Long SerialVersionuid = 1L ؛ / ** الرقم*/ معرف طويل خاص ؛ / ** الاسم*/ اسم السلسلة الخاصة ؛ / ** العمر*/ عصر عدد صحيح خاص ؛ / ** الوصف*/ وصف السلسلة الخاصة ؛ / ** وقت الخلق*/ سلسلة خاصة CreateTM ؛ // getter و setter حذفت}عند استخدام SpringData ، يحتاج إلى تعيين اسم الفهرس واكتب في فئة الكيان. إذا ما قورنت مع قواعد البيانات التقليدية ، فهي تعادل المكتبات والجداول.
تجدر الإشارة إلى أن كلا من الفهرس والنوع يجب أن يكونا في حالة صغيرة !!!
طبقة داو
الواجهة العامة userDao يمتد ElasticsearchRepository <مستخدم ، Long> {}طبقة DAO بسيطة نسبيًا هنا ، فقط ترث فئة ElasticsearchRepository. الأساليب الرئيسية هي حفظ وحذف والبحث. طريقة الحفظ مثل إدراج وتحديث. إذا لم يكن هناك ، فسيتم إضافته وإذا كان هناك واحد ، فسيتم تغطيته. تتمثل طريقة الحذف بشكل أساسي في حذف مكتبات البيانات والفهرس. بالنسبة للبحث ، فهو استفسار ، بما في ذلك بعض الاستعلامات الشائعة الاستخدام ، مثل ترقيم الصفحات ، والأوزان ، إلخ.
طبقة الخدمة
servicepublic class userviceImpl تنفذ المستخدمين {autowired userDao userDao ؛ Override public boolean insert (مستخدم المستخدم) {boolean falg = false ؛ حاول {userDao.save (user) ؛ falg = صحيح ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } إرجاع falg ؛ } Override Public List <Sether> Search (String SearchContent) {QueryStringQueryBuilder Builder = new QueryStringQueryBuilder (SearchContent) ؛ System.out.println ("بيان الاستعلام:"+builder) ؛ iterable <Sether> searchResult = userDao.search (builder) ؛ iterator <Sether> iterator = searchResult.iterator () ؛ قائمة <Sether> list = new ArrayList <Sether> () ؛ بينما (iterator.hasnext ()) {list.add (iterator.next ()) ؛ } قائمة الإرجاع ؛ } Override Public List <Sether> SearchUser (integer pagenumber ، integer pagesize ، string searchcontent) {// pagination parameters pageable abilable = new pagerequest (pagenumber ، pagesize) ؛ QueryStringQueryBuilder Builder = new QueryStringQueryBuilder (SearchContent) ؛ SearchQuery SearchQuery = New NativeSearchQueryBuilder (). withpageable (قابلة للتماس). System.out.println ("بيان الاستعلام:" + searchquery.getQuery (). ToString ()) ؛ page <Sether> searchPagerEsults = userDao.search (searchquery) ؛ return searchpageresults.getContent () ؛ } Override Public List <Seter> SearchUserByWeight (String SearchContent) {// Query وفقًا للدالة الأوزان FunctEquiller functionScorequeryBuilder = QueryBuilders.FunctionScorequery () .add (querybuilders.boolquery (). ScoreFunctionBuilders.WeightFactorFunction (10)) .Add (QueryBuilders.Boolquery (). System.out.println ("بيان الاستعلام:" + functionScorequeryBuilder.toString ()) ؛ iterable <Sether> searchResult = userDao.search (functionScorequeryBuilder) ؛ iterator <Sether> iterator = searchResult.iterator () ؛ قائمة <Sether> list = new ArrayList <Sether> () ؛ بينما (iterator.hasnext ()) {list.add (iterator.next ()) ؛ } قائمة الإرجاع ؛ }}لقد كتبت هنا ببساطة عدة طرق ، الطريقة الرئيسية هي الاستعلام. تشمل الاستعلامات البحث عن النص الكامل ، والاستعلام عن ترقيم الصفحات ، والاستعلام عن الوزن. ما يجب شرحه هو استعلام الوزن. كلما ارتفعت درجة الوزن ، زادت نتيجة الاستعلام. إذا لم يتم تعيين درجة للبيانات الأخرى ، فإن درجتها الافتراضية هي 1. إذا كنت لا ترغب في الاستعلام عن هذه العبارات ، فما عليك سوى استخدام SetMinsCore لتعيينها إلى أكبر من 1.
اختبار الكود
اتصل بالواجهة لإضافة بيانات
بيانات جديدة:
post http: // localhost: 8086/api/user {"id": 1 ، "name": "Zhang San" ، "Age": 20 ، "Description": SI هو مهندس اختبار "،" CreateTM ":" 1980-2-15 19:01:32 "} {" id ": 3 ،" name ":" Wang Wu "،" Age ":" Description ": إجراء استعلام نصي كامل
بسأل
http: // localhost: 8086/api/user؟ searchContent = Engineer
يعود
[{"ID": 2 ، "name": "Li Si" ، "Age": 14 ، "Description": "Li Si is a test Engineer" ، "2018-4-25 11:07:42"} ، {"id": 3 ، "name": "Wang Wu" ، "Age": "Description": "Wang Wu هو مهندس عملية وصيانة" ، "CreateTM": "2016-8-21 06:11:32}] أداء استعلام ترقيم الصفحات
بسأل
http: // localhost: 8086/api/user؟ pagenumber = 0 & pagesize = 2 & searchContent = Engineer
يعود
[{"id": 2 ، "name": "li si" ، "Age": 14 ، "Description": أداء الاستعلام عن الوزن
بسأل
http: // localhost: 8086/api/user2؟ searchContent = li si
يعود
[{"id": 2 ، "name": "Li Si" ، "Age": 24 ، "description":بيان طباعة استعلام الوزن:
بيان الاستعلام: {{"function_score": {"الوظائف": [{"filter": {"bool": {"bool": {"should: {"bool": {"يجب أن": {"match": {"description": {"query": "li si" ، "type": "boolean"}}}}}} ،ملاحظة: في الاختبار ، نظرًا لأن الحد الأدنى من وزن setMinsCore يتم تقسيمه إلى 2 ، فلن يتم عرض بيانات غير ذات صلة. إذا كنت ترغب في عرضه ، فما عليك سوى إزالته في الكود.
بعد إضافة بيانات جديدة ، يمكنك إدخال: http: // localhost: 9200/_plugin/head/in the browser
ثم انقر فوق الاستعلام الأساسي لعرض البيانات المضافة. إذا كنت ترغب في استخدام استعلام البيانات ، فيمكنك لصق عبارة الاستعلام المطبوعة بواسطة وحدة التحكم في البرنامج إلى واجهة الاستعلام للاستعلام!
ملاحظة: قمت بتثبيت Elasticsearch هنا على Windows وقمت بتثبيت رأس البرنامج المساعد ES. خطوات التثبيت المحددة في نهاية المقالة.
بالإضافة إلى SpringData ، هناك بالفعل طرق أخرى لتشغيل Elasticsearch.
على سبيل المثال ، استخدم واجهة برمجة تطبيقات Elasticsearch الأصلية واستخدم فئة TransportClient لتنفيذها.
أو استخدمه للتغليف بحلول الربيع ، فقط حقن الفول في طبقة الخدمة.
مثال:
@autowired elasticsearchtemplate elasticsearchTemplate ؛
ومع ذلك ، فإن الأساليب المذكورة أعلاه لها قيودها ، أي مع تغيير إصدار Elasticsearch ، فإن واجهة برمجة تطبيقات Java ذات الصلة يتم ضبطها باستمرار ، أي بعد تغيير إصدار الخادم من Elasticsearch ، قد يلزم إعادة كتابة رمز العميل.
لذلك ، فإنه يقدم JestClient أداة مفيدة للغاية. إنه يلف Elasticsearch ويملأ الفجوة في عميل Elasticsearch HttPrest Interface. إنه مناسب للإصدارات Elasticsearch 2.x أو أعلى ، وليس هناك حاجة لتغيير الكود بسبب تغيير إصدار خادم Elasticsearch!
Jestclient
أضف أولاً التبعيات التالية في Maven:
<Rependency> <roupiD> io.searchbox </groupId> <StifactId> Jest </artifactId> <الإصدار> 5.3.3 </version> </preminent>
ثم اكتب رمز الاختبار ذي الصلة.
يجب أن تكون التعليقات في الكود كاملة للغاية ، لذلك لن أتحدث كثيرًا عن الكود هنا.
استيراد java.util.arraylist ؛ استيراد java.util.list ؛ استيراد org.elasticsearch.index.query.querybuilders ؛ استيراد org.elasticsearch.search.builder.searchSourceBuilder ؛ استيراد com.pancm.pojo.user io.searchbox.client.jestclientfactory ؛ import io.searchbox.client.jestresult ؛ import io.searchbox.client.config.httpclientconfig ؛ io.searchbox.core.documentResult ؛ import io.searchbox.core.index ؛ import io.searchbox.core.search ؛ import io.searchbox.indices.createindex ؛ import io Jesttest {private static Jestclient JestClient ؛ indexname indexName static static = "userIndex" ؛ // private Static String IndexName = "userIndex2" ؛ سلسلة ثابتة خاصة typename = "المستخدم" ؛ سلسلة ثابتة للسلسلة الثابتة = "http://192.169.2.98:9200" ؛ // static string leastips = "http://127.0.0.1:9200" ؛ الباطل الثابت الرئيسي الرئيسي (سلسلة [] args) يلقي الاستثناء {JestClient = getJestClient () ؛ insertbatch () ؛ serach1 () ؛ serach2 () ؛ serach3 () ؛ JestClient.close () ؛ } private static jestclient getJestClient () {JestClientFactory Factory = New JestClientFactory () ؛ مصنع. Return Factory.getObject () ؛ } public static void insertbatch () {list <Object> objs = new ArrayList <Object> () ؛ Objs.add (مستخدم جديد (1L ، "Zhang San" ، 20 ، "Zhang San هو مهندس تطوير Java" ، "2018-4-25 11:07:42")) ؛ objs.add (مستخدم جديد (2L ، "Li Si" ، 24 ، "Li Si هو مهندس اختبار" ، "1980-2-15 19:01:32")) ؛ OBJS.Add (مستخدم جديد (3L ، "Wang Wu" ، 25 ، "Wang Wu هو مهندس عملية وصيانة" ، "2016-8-21 06:11:32")) ؛ نتيجة منطقية = خطأ ؛ حاول {result = insertBatch (JestClient ، indexName ، typename ، objs) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } system.out.println ("دفعة جديدة:"+نتيجة) ؛ } / *** Search Text Full* / public static void serach1 () {String Query = "Engineer" ؛ Try {SearchSourceBuilder SearchSourceBuilder = New SearchSourceBuilder () ؛ SearchOrceBuilder.query (QueryBuilders.querystringQuery (Query)) ؛ // إعداد الصفحة SearchSourceBuilder.from (0) .Size (2) ؛ System.out.println ("بيان استعلام البحث الكامل النص:"+SearchSourceBuilder.toString ()) ؛ System.out.println ("إرجاع البحث عن النص الكامل النتيجة:"+Search (JestClient ، indexName ، typename ، searchourceBuilder.toString ())) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }} / *** بحث دقيق* / public static void serach2 () {try {searchSourceBuilder SearchOrceBuilder = new searchourceBuilder () ؛ SearchOrceBuilder.query (QueryBuilders.TermQuery ("Age" ، 24)) ؛ System.out.println ("بيان استعلام البحث الدقيق:"+searchourceBuilder.toString ()) ؛ System.out.println ("البحث الدقيق النتيجة:"+Search (JestClient ، indexName ، typename ، searchousourceBuilder.toString ())) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }} / *** search الفاصل* / public static void serach3 () {string createTM = "createTM" ؛ سلسلة من = "2016-8-21 06:11:32" ؛ سلسلة إلى = "2018-8-21 06:11:32" ؛ Try {SearchSourceBuilder SearchSourceBuilder = New SearchSourceBuilder () ؛ SearchSourceBuilder.query (QueryBuilders.RangeQuery (CreateTM) .gte (من) .lte (إلى)) ؛ System.out.println ("بيان البحث الفاصل:"+SearchSourceBuilder.toString ()) ؛ system.out.println ("إرجاع البحث الفاصل النتيجة:"+البحث (JestClient ، indexName ، typename ، searchourceBuilder.toString ())) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }} / ** * إنشاء فهرس * param indexname * return * @throws استثناء * / boolean العام createIndex (JestClient JestClient ، string indexname) يلقي استثناء {JestResult jr = JestClient.Execute (جديد createIndex.builder (indexName) .build ()) ؛ return Jr.issucceeded () ؛ } / ** * بيانات جديدة * param indexName * param typename * param source * return * @throws استثناء * / public boolean insert (JestClient JestClient ، string indexname ، string typename ، String source) rems stispion {putmapping = new putmapping.builder (indexName ، typename ، JestResult Jr = JestClient.execute (putmapping) ؛ return Jr.issucceeded () ؛ } / ** * بيانات الاستعلام * param indexName * param typename * return * throws استثناء * / سلسلة ثابتة عامة getIndExMapping (JestClient JestClient ، string indexName ، String typename) يلقي استثناء {getMapping getMapping = new getMapping.builder (). addindex). JestResult Jr = JestClient.execute (getMapping) ؛ return jr.getjsonstring () ؛ } / ** * أضف بيانات في دفعات * param indexName * param typename * param objs * @throurn stisple bulk.builder (). defaultIndex (indexName) .DefaultType (typename) ؛ لـ (Object OBJ: OBJS) {index index = new index.builder (obj) .build () ؛ bulk.addacte (index) ؛ } bulkresult br = jestclient.execute (bulk.build ()) ؛ إرجاع br.issucceeded () ؛ } / ** * Search Text Full Full * param indexName * param typename * param query * return * throws استثناء * / بحث سلسلة ثابتة عامة (JestClient JestClient ، string indexname ، string typename ، string query) rems stispion {search JestResult Jr = JestClient.execute (Search) ؛ // system.out.println ("-"+jr.getjsonstring ()) ؛ // system.out.println ("-"+jr.getsourceasobject (user.class)) ؛ return Jr.GetSourCeasString () ؛ } / ** * حذف الفهرس * param indexName * RETURN * @Throws استثناء * / الحذف المنطقي العام (JestClient JestClient ، string indexname) يلقي استثناء {JestResult jr = JestClient.execute (new deledeex.builder (indexname) .build ()) ؛ return Jr.issucceeded () ؛ } / ** * حذف البيانات * param indexName * param typename * param id * regurn * @throws استثناء * / public boolean delete (JestClient JestClient ، string indexname ، string typename ، string id) throws request {documentResult dr = delete.builder (id) .index (indexName) .type (typename) .build ()) ؛ إرجاع Dr.issuceded () ؛ }ملاحظة: قبل الاختبار ، دعنا أولاً نوضح أن إصدار Elasticsearch المثبت على نظام Windows المحلي هو 2.3.5 ، وإصدار Elasticsearch المثبت على خادم Linux هو 6.2.
نتائج الاختبار
البحث عن النص الكامل
بيان استعلام البحث الكامل النص: {"من": 0 ، "الحجم": 2 ، "استعلام": {"query_string": {"Query": "Engineer"}}} Full Text Search Returns: {"ID": 1 ، "name": "Zhang San" ، Engineer "،" CreateTM ":" 2018-4-25 11:07:42 "} ، {" id ": 2 ،" name ":تطابق البحث
بيان استعلام بحث دقيق: {"Query": {"Term": {"Age": 24}}} إرجاع بحث دقيق النتيجة: {"id": 2 ، "name": "Li Si" ، "Age": 24 ، "Description":البحث الفاصل الزمني
بيان البحث الفاصل: {"Query": {"Range": {"CreateTM": {"from": "2016-21 06:11:32" ، "to": "2018-8-21 06:11:32 San "،" Age ": 20 ،" Description ":بعد إضافة بيانات جديدة ، يمكننا الذهاب إلى Linux Kibana لإجراء الاستعلامات ذات الصلة ، ونتائج الاستعلام هي كما يلي:
ملاحظة: Kibana هو برنامج مفتوح المصدر في الأيائل. يوفر Kibana واجهات ويب صديقة لتحليل السجل لـ Logstash و Elasticsearch للمساعدة في تلخيص وتحليل وتفتيش سجلات البيانات المهمة.
تتماشى النتائج التي تم إرجاعها عن طريق الاختبار في الكود أعلاه مع توقعاتنا. من بينها ، يتم استخدام جزء صغير فقط من JestClient. لمزيد من الاستخدام ، يمكنك التحقق من الوثائق الرسمية لـ JestClient.
تثبيت Elasticsearch على Windows
1. تحضير الوثيقة
تنزيل العنوان: https://www.elastic.co/Downloads
حدد الإصدار المرتبط بـ Elasticsearch ، ثم حدد ملف اللاحقة zip file لتنزيله ، ثم قم بفك ضغطه بعد التنزيل.
2. ابدأ Elasticsearch
انتقل إلى دليل bin وقم بتشغيل elasticsearch.bat
ثم أدخل: LocalHost: 9200 على التصفح
عرض الواجهة بنجاح يعني النجاح!
3. قم بتثبيت المكون الإضافي ES
تثبيت رئيس واجهة إدارة الويب
أدخل دليل bin ، فتح CMD ، وأدخل واجهة DOS
أدخل: plugin install mobz/elasticsearch-head
قم بتنزيل
بعد التنزيل الناجح ، أدخل: http: // localhost: 9200/_plugin/head/
إذا تم عرض الواجهة ، فسيكون التثبيت ناجحًا!
4. تسجيل الخدمة
أدخل دليل bin ، فتح CMD ، وأدخل واجهة DOS
يدخل:
Service.Bat installservice.bat ابدأ
بعد النجاح ، أدخل
Services.MSC
القفز إلى واجهة خدمة الخدمة لعرض حالة تشغيل ES مباشرة!
آخر
Elasticsearch الرسمي عنوان API العنوان:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html
عنوان JestClientGithub:
https://github.com/searchbox-io/jest (التنزيل المحلي)
أنا وضعت المشروع على جيثب.
https://github.com/xuwujing/springboot (التنزيل المحلي)
لخص
ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يكون لمحتوى هذه المقالة قيمة مرجعية معينة لدراسة أو عمل الجميع. إذا كان لديك أي أسئلة ، فيمكنك ترك رسالة للتواصل. شكرا لك على دعمك إلى wulin.com.