- 엘라스틱서치(Elasticsearch)의 JSON 기반 쿼리 언어로, 복잡한 검색을 수행
기본 사용법
- match : 텍스트와 관련성 있는 문서 검색
- term : 정확히 일치하는 값을 검색
- range : 숫자, 날짜, 또는 범위를 검색
Query DSL - Term Query
- 예제 코드를 통해 이해해 보자
- term는 정확히 일치하는 것만 나온다.
const axios = require('axios');
const url = 'http://localhost:9200/test_index2/_search';
const query = {
query: {
term: {
name:'react'
}
}
};
axios.post(url, query)
.then(res => {
const jsonRes = JSON.stringify(res.data, null, 2);
console.log(jsonRes)
})
.catch(err =>{
console.error(err);
});
name이 react와 일치하는 것만 조회
- 하지만 조회한 결과는 다음과 같다.
$ node 12.dsl_term.js
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.7385771,
"hits": [
{
"_index": "test_index2",
"_id": "10",
"_score": 0.7385771,
"_source": {
"name": "Advanced React React React Patterns",
"description": "Explore advanced techniques in React to build scalable and maintainable applications."
}
},
{
"_index": "test_index2",
"_id": "15",
"_score": 0.6802684,
"_source": {
"name": "Advanced React React React Patterns Patterns Patterns",
"description": "Explore advanced techniques in React to build scalable and maintainable applications."
}
}
]
}
}
- 이렇게 나온 이유를 찾아보니 엘라스틱 서치에서는 기본 필드를 text 형태(
["advanced", "react", "react", "react", "patterns"] )로 저장한다고 한다. 그래서 내가 react와 일치하는 값을 얻고 싶어도 같은 react라는 이름이 들어간 값이 나오는 것이다.
- 이 문제를 해결하기 위해 위 코드를 아래와 같이 수정했다.
const axios = require('axios');
const url = 'http://localhost:9200/test_index2/_search';
const query = {
query: {
term: {
"name.keyword": "react"
}
}
};
axios.post(url, query)
.then(res => {
const jsonRes = JSON.stringify(res.data, null, 2);
console.log(jsonRes)
})
.catch(err =>{
console.error(err);
});
query 부분을 name.keword로 변경해 아래와 같이 실행하면

- 아래와 같이 일치하는 값이 없다고 뜨는 것을 확인할 수 있다.
Query DSL - Range Query
const axios = require('axios');
const addRangeData = async () => {
const url = 'http://localhost:9200/test_index2/_doc';
const data = [
{id : 1, name : 'Product A', price : 100},
{id : 2, name : 'Product B', price : 200},
{id : 3, name : 'Product C', price : 300},
{id : 4, name : 'Product D', price : 400}
]
for(let i = 0; i < data.length; i++) {
const res = await axios.post(`${url}/${data[i].id}`, data[i]);
console.log(res.data);
}
}
addRangeData().catch(err => {
console.error(err);
})
const axios = require('axios');
const url = 'http://localhost:9200/test_index2/_search';
const query = {
query: {
range: {
price:{
gte: 200,
lte: 400
}
}
}
};
axios.post(url, query)
.then(res => {
const jsonRes = JSON.stringify(res.data, null, 2);
console.log(jsonRes)
})
.catch(err =>{
console.error(err);
});
- 위 코드를 실행 시 price가 200 ~ 400 사이인 데이터들이 나온다.
