Прекарах влудяващи няколко часа, опитвайки се да разбера как да създам заявка за търсене, която да направи това:
Връща всички документи, които имат низ на заявка навсякъде в което и да е поле, но само ако поле1 няма точна стойност1 ИЛИ поле2 има точна стойност2.
След твърде много време, опитвайки се да намеря добри обяснения или примери в документите и търсейки в StackOverflow, стигнах до това:
query: { bool: { minimum_should_match: 1, must: [{ wildcard: { _all: { value: `*${querystring}*` } } }], should: [{ not: { term: { field1: value1 } } }, { term: { field2: value2 } }] } }
Да, знам, че трябва да използвам стратегия nGram вместо заместващи знаци. Ще правя това в нашето приложение. Но тази публикация е за синтаксиса на заявката. И открих, че горното е абсурдно трудно да се сглоби.
Запазвайки нещата във формат JSON с цел преносимост, предлагам тази алтернатива:
query: [ { _all: `*${querystring}*` }, ‘AND’, [[ ‘NOT’, { field1: value1 } ], ‘OR’, { field2: value2 } ] ]
Освен че е по-лесно за разбиране, това е по-лесно за анализ:
- Обектите винаги ще имат ключ с име на поле (или специалното `_all`). Опциите за търсене в това поле могат да бъдат събрани под ключ `_options` или нещо друго в този обект.
- Заместващият знак се подразбира от наличието на * (буквалните звездички могат да бъдат екранирани).
- Членовете на низа на масива на заявката винаги са оператори.
- Вложените масиви са за групиране на оператори с полета и за определяне на приоритет.
Не е много красиво и честно казано не знам нищо за сложността на Elasticsearch, но може да се сериализира в JSON и е много по-просто.
Джед Верити е основател на Dataverse Consulting (скоро ще бъде Sentient Applications) и дългогодишен защитник на JavaScript, чиято работа става все по-лесна сега, когато езикът показва разпознаваеми признаци на зрялост.