티스토리 뷰

반응형

※ 구글링해도 못 찾아서 내가 땅 한번 파보고 쓰는 블로그 ※

 

 전제 1 

나는 여행 계획을 짜려고 한다. 르뱅쿠키도 먹고 싶고 미스사이공 뮤지컬도 보고 싶은데, 어디 좋은 곳 없을까?

그래서 난 MongoDB 데이터베이스에서

  1. 자유여행 이면서
  2. 르뱅베이커리쿠키를 먹고
  3. 미스사이공 뮤지컬도 볼 수 있는

도시가 포함된 여행 계획들을 검색하고자 한다.

 

 MongoDB 도큐먼트 구조 

// doc 1
{
   "tripId": "AABB123",
   "tripLoc": "Domestic",
   "tripType": "free",
   "cities": [
      {
         "cityName": "Seoul",
         "todo": [
            {
               "category": "eat",
               "name": "levainbakery"
            },
            {
               "category": "musical",
               "name": "Miss Saigon"
            }
         ]
      },
      {
         "cityName": "Daejeon",
         "todo": [
            {
               "category": "eat",
               "name": "sunsimdang"
            }
         ]
      }
   ]
}

// doc 2
{
   "tripId": "CCDD456",
   "tripLoc": "Overseas",
   "tripType": "free",
   "cities": [
      {
         "cityName": "NY",
         "todo": [
            {
               "category": "eat",
               "name": "levainbakery"
            },
               {
               "category": "eat",
               "name": "Red Poke"
            }
         ]
      }
   ]
}

 MongoDB 검색 쿼리 

db.test.find(
{ "tripType" : "free",
  "cities" : { "$elemMatch" : { "$and" : [
    { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "levainbakery"}]}}},
       { "todo" : { "$elemMatch" : { "category" : "musical", "$and" : [{ "name" : "Miss Saigon"}]}}}]}}}
).pretty()
// 검색 결과
{
        "_id" : ObjectId("60f90701ef19bebb6341907e"),
        "tripId" : "AABB123",
        "tripLoc" : "Domestic",
        "tripType" : "free",
        "cities" : [
                {
                        "cityName" : "Seoul",
                        "todo" : [
                                {
                                        "category" : "eat",
                                        "name" : "levainbakery"
                                },
                                {
                                        "category" : "musical",
                                        "name" : "Miss Saigon"
                                }
                        ]
                },
                {
                        "cityName" : "Daejeon",
                        "todo" : [
                                {
                                        "category" : "eat",
                                        "name" : "sunsimdang"
                                }
                        ]
                }
        ]
}

// 검색 결과에서 난 tripId만 보고 싶다. default로 보여지는 _id도 안 보고싶다. 
db.test.find(
{ "tripType" : "free",
  "cities" : { "$elemMatch" : { "$and" : [
    { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "levainbakery"}]}}},
       { "todo" : { "$elemMatch" : { "category" : "musical", "$and" : [{ "name" : "Miss Saigon"}]}}}]}}}
, {tripId : 1, _id : 0}).pretty() 
 // 검색 결과
 { "tripId" : "AABB123" }

 JAVA 코드 

@Override
public Schedule getTourSchedule() {
    Query query = new Query();
    query.addCriteria(Criteria.where("tripType").is("free"));

    List<Criteria> todoCriteria = new ArrayList<>();
    todoCriteria.add(Criteria.where("todo").elemMatch(
            Criteria.where("category").is("eat").andOperator(Criteria.where("name").is("levainbakery"))));
    todoCriteria.add(Criteria.where("todo").elemMatch(
            Criteria.where("category").is("musical").andOperator(Criteria.where("name").is("Miss Saigon"))));
    query.addCriteria(Criteria.where("cities").elemMatch(new Criteria().andOperator(todoCriteria.toArray(new Criteria[todoCriteria.size()]))));

    return mongoTemplate.find(query, Schedule.class);
}

 전제 2 

르뱅 베이커리레드포케를 먹을 수 있는 여행 계획을 짜고 싶다.

 MongoDB 검색 쿼리 

db.test.find(
{ "tripType" : "free",
  "cities" : { "$elemMatch" : { "$and" : [
  { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "levainbakery"}]}}},
  { "todo" : { "$elemMatch" : { "category" : "eat", "$and" : [{ "name" : "Red Poke"}]}}}]}}}
, {tripId : 1, _id : 0}).pretty()
// 검색 결과
{ "tripId" : "CCDD456" }

JAVA 코드 : For문을 이용하여 이중 배열 찾는 쿼리 예제 

@Override
public Schedule getTourSchedule() {

    Query query = new Query();
    query.addCriteria(Criteria.where("tripType").is("free"));

    List<String> goList = new ArrayList<>(); // 가고 싶은 음식점 리스트
    goList.add("levainbakery");
    goList.add("Red Poke");

    List<Criteria> todoCriteria = new ArrayList<>();
    for (String storeName : goList) { // For문을 활용하여 가고 싶은 음식점 리스트를 기반으로 쿼리 생성
        todoCriteria.add(Criteria.where("todo").elemMatch(
                Criteria.where("category").is("eat").andOperator(Criteria.where("name").is(storeName))));
    }
    query.addCriteria(Criteria.where("cities").elemMatch(new Criteria().andOperator(todoCriteria.toArray(new Criteria[todoCriteria.size()]))));

   return mongoTemplate.find(query, Schedule.class);
}

 

끄읕ⓙ

반응형
반응형