강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

호기심고양이님의 프로필 이미지
호기심고양이

작성한 질문수

남박사의 파이썬으로 실전 웹사이트 만들기

게시판만들기 - 글 리스트

DB 검색하면 데이터가 없습니다. 라고 나와요. 5시간을 찾아봐도 모르겠어서 문의드려봅니다.

해결된 질문

작성

·

30

·

수정됨

0

안녕하세요

저의 환경은

윈도우 11이고 파이선 3.12 버전입니다.

몽고DB는 8.2.3 x64입니다.

ms 엣지 브라우저 버전 143.0.3650.96 (공식 빌드) (64비트) 입니다.

 

구글에서 긁어오는게 문제가 있어서

네이버로 변경하여 긁어왔습니다.

DB에 35개의 데이터를 넣었습니다.

Studio 3T 프로그램으로 검새하면

db.getCollection("board").find({

$or:[

// {title: { $regex: "이유", $options: "i" }},

{name:{ $regex: "테스터", $options: "i" }}

]

})

위의 쿼리로 검색을 했을 때

name = '테스터'로 하면 35개 전부 나오고

title = '이유'로 검색하면 3건이 나옵니다.

 

그런데 웹에서 list.html 검색에서는 0건으로 데이터가 없다고 나옵니다.

원인을 아무리 찾아도 모르겠어서 문의드려봅니다.

 

image.png

위와 같이 네이버에서 검색하여 DB에 넣음

image.png

title 이유로 검색하면 3건

name 테스터로 검색하면 35건 조회됩니다.

image.png

위와 같이 제목, '이유'로 검색하면 3건이 나와야 하는데

image.png

위와 같이 데이터가 없습니다. 라고 나옵니다.

    # 검색 대상이 한개라도 존재할 경우 query 변수에 $or 리스트를 쿼리 합니다.
    if len(search_list) > 0:
        query = {"$or": search_list}

    print(query)
    # datas_count = board.count_documents({})  # 정확한 카운트 방식
    datas_count = board.count_documents(query)
    print(datas_count)

위와 같이 print로 값을 보면

{'$or': [{'title': {'regex': '이유'}}]}

0

127.0.0.1 - - [11/Jan/2026 17:42:01] "GET /list?search=0&keyword=이유 HTTP/1.1" 200 -

이렇게 나옵니다.

쿼리는 title 이유라고 잘 들어가는 것 같은데

검색 결과가 0건으로 나옵니다.

DB에서 검색이 제대로 안되는걸로 보이는데 어느부분일지 찾지 못하고 있습니다.

 

아래는 전체 소스코드 입니다.

 

< run.py 전체 코드 >


from flask import Flask
from flask import request
from flask import render_template
from flask_pymongo import PyMongo
from datetime import datetime
from bson.objectid import ObjectId
from flask import abort
from flask import redirect
from flask import url_for
import time
import math

app = Flask(__name__)

app.config["MONGO_URI"] = "mongodb://localhost:27017/myweb"
mongo = PyMongo(app)

@app.template_filter("formatdatetime")
def format_datetime(value):
    if value is None:
        return ""
    
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    value = datetime.fromtimestamp((int(value) / 1000)) + offset
    return value.strftime('%Y-%m-%d %H:%M:%S')

@app.route("/list")
def lists():
    page = request.args.get("page", default=1, type=int)
    limit = request.args.get("limit", 5, type=int)

    search = request.args.get("search", -1, type=int)
    keyword = request.args.get("keyword", type=str)

    query = {}
    search_list = []

    if search == 0:
        search_list.append({"title": {"regex": keyword}})
    elif search == 1:
        search_list.append({"contents": {"regex": keyword}})
    elif search == 2:
        search_list.append({"title": {"regex": keyword}})
        search_list.append({"contents": {"regex": keyword}})
    elif search == 3:
        search_list.append({"name": {"regex": keyword}})

    if len(search_list) > 0:
        query = {"$or": search_list}

    print(query)

    board = mongo.db.board
    datas = board.find(query).skip((page - 1) * limit).limit(limit)
    datas_count = board.count_documents(query)
    print(datas_count)

    tot_count = datas_count
    last_page_num = math.ceil(tot_count / limit)

    block_size = 5
    block_num = int((page - 1) / block_size)
    block_start = int((block_size * block_num) + 1)
    block_last = math.ceil(block_start + (block_size - 1))

    return render_template(
        "list.html",
        datas=datas,
        datas_count=datas_count,
        limit=limit,
        page=page,
        block_start=block_start,
        block_last=block_last,
        last_page_num=last_page_num,
        search=search,
        keyword=keyword)

@app.route("/view/<idx>")
def board_view(idx):
    if idx is not None:
        page = request.args.get("page")
        search = request.args.get("search")
        keyword = request.args.get("keyword")

        board = mongo.db.board
        data = board.find_one({"_id": ObjectId(idx)})

        if data is not None:
            result = {
                "id": data.get("_id"),
                "name": data.get("name"),
                "title": data.get("title"),
                "contents": data.get("contents"),
                "pubdate": data.get("pubdate"),
                "view": data.get("view")
            }

            return render_template("view.html", result=result, page=page, search=search, keyword=keyword)
    return abort(404)

@app.route("/write", methods=["GET", "POST"])
def board_write():
    if request.method == "POST":
        name = request.form.get("name")
        title = request.form.get("title")
        contents = request.form.get("contents")
        print(name, title, contents)

        current_utc_time = round(datetime.utcnow().timestamp() * 1000)
        board = mongo.db.board
        post = {
            "name": name,
            "title": title,
            "contents": contents,
            "pubdate": current_utc_time,
            "view": 0
        }

        x = board.insert_one(post)
        print(x.inserted_id)

        return redirect(url_for("board_view", idx=x.inserted_id))
    else:
        return render_template("write.html")

if __name__ == "__main__":
    app.run(debug=True, port=9000)

 

< list.html 전체 코드 >

<script>
    function search() {
        var v_search = document.getElementById("search").value;
        var v_keyword = document.getElementById("keyword").value;

        if(v_search == "" || v_keyword == "") {
            return false;
        } else {
            self.location.href = "{{url_for('lists')}}?search=" + v_search + "&keyword=" + v_keyword;
        }
    }
</script>

<!-- % if datas_count() > 0 %} # Deprecated 됨-->
{% if datas_count > 0 %}
<table>
    <thead>
        <tr>
            <td>번호</td>
            <td>제목</td>
            <td>이름</td>
            <td>날짜</td>
            <td>조회수</td>
        </tr>
    </thead>
    <tbody>
        <!-- 반복되는 구간 -->
         {% for data in datas %}
        <tr>
            <td>{{loop.index + ((page - 1) * limit)}}</td>
            <td><a href="{{url_for('board_view', idx=data._id, page=page, search=search, keyword=keyword)}}">{{data.title}}</a></td>
            <td>{{data.name}}</td>
            <td>{{data.pubdate | formatdatetime}}</td>
            <td>{{data.view}}</td>
        </tr>
        {% endfor %}
        <!-- 반복되는 구간 끝 -->
    </tbody>    
</table>
{% if block_start - 1 > 0 %}
    <a href="{{url_for('lists', page=block_start - 1, search=search, keyword=keyword)}}">[이전]</a>
{% endif %}

{% for i in range(block_start, block_last + 1) %}
    {% if i > last_page_num %}
        {{ i }}
    {% else %}
        {% if i == page %}
            <b>{{ i }}</b>
        {% else %}
            <a href="{{url_for('lists', page=i, search=search, keyword=keyword)}}">{{ i }}</a>
        {% endif %}
    {% endif %}
{% endfor %}

{% if block_last < last_page_num %}
    <a href="{{url_for('lists', page=block_last + 1, search=search, keyword=keyword)}}">[다음]</a>
{% endif %}

<select name="search" id="search">
    <option value="" {% if search == '' or search == -1 %} selected {% endif %}>검색대상</option>
    <option value="0" {% if search == 0 %} selected {% endif %}>제목</option>
    <option value="1" {% if search == 1 %} selected {% endif %}>내용</option>
    <option value="2" {% if search == 2 %} selected {% endif %}>제목+내용</option>
    <option value="3" {% if search == 3 %} selected {% endif %}>작성자</option>
</select>

<input type="text" name="keyword" id="keyword" {% if keyword != "" %} value={{keyword}} {% endif %}>
<input type="button" value="검색" onclick="search()">

{% else %}
<h3>데이터가 없습니다.</h3>

{% endif %}

<a href="{{url_for('board_write')}}">글작성</a>

오타가 있는지 문제가 될만한 부분이 있는지 5시간이나 찾아봤는데 도저히 못찾아서 문의드려봅니다.

봐주셔서 감사합니다.

버전 143.0.3650.96 (공식 빌드) (64비트)

버전 143.0.3650.96 (공식 빌드) (64비트)ㅍ

답변 1

1

안녕하세요, 인프런 AI 인턴입니다. 호기심고양이님.

제공하신 내용을 기반으로 문제점을 파악해 보겠습니다.

DB 검색 시 데이터가 없습니다 라고 나오는 문제는 대개 제대로 된 쿼리가 전달되지 않거나 데이터베이스 설정의 문제일 수 있습니다. 현재 문제가 ‘이유’라는 키워드로 검색할 때 결과가 나오지 않는 점입니다. 코드를 살펴보니 잘못된 부분이 있습니다:

  1. 정규 표현식 ($regex) 형식: 검색에 사용된 regex의 ‘$‘가 누락되었습니다.
    ”`python

    Before

    search_list.append({“title”: {“regex”: keyword}})

# After
search_list.append({“title”: {“$regex”: keyword}})


2. **대소문자 구분 사용 안 함**: 정규 표현식을 사용할 때 대소문자를 구분하지 않도록 설정하는 것이 좋습니다. `$options: "i"` 를 추가하면 좋습니다.
   ```python
   search_list.append({"title": {"$regex": keyword, "$options": "i"}})
  1. 빈 문자열 & None 처리: keyword가 None이 아니라 빈 문자열로 설정되었는지 다시 확인하여야 합니다. 만약 keyword가 없으면 빈 문자열로 처리하는 방식이 문제를 해결하는 데 도움이 될 수 있습니다.
   keyword = request.args.get("keyword", "", type=str)
  1. 확장된 print 디버깅: 더 나은 디버깅을 위해 쿼리를 명확히 출력하고 실제로 MongoDB에서 작동하는지 확인해 보세요.

  2. 브라우저 캐시 문제: 가끔 브라우저 캐시가 이전 응답을 앞에 놓을 수 있습니다. 이 경우, 캐시를 지워 보세요.

실수로 놓친 부분이 더 있다고 판단되면, 아래 유사한 문제를 다룬 질문을 참고하세요:
- 게시판 검색기능 구현 후 데이터를 검색하여도 데이터 없음으로 나옵니다.
- 검색기능 질문
- 검색어 한글입력

이 점검 목록을 활용하시면서 몇 가지 수정을 해보세요. 문제가 지속된다면 추가적으로 궁금한 사항이 있는 경우, 답변된 글에 비슷한 사례들이 제공되어 있으니 참고해 보시기 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해 드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

안녕하세요

관심과 답글 감사합니다.

 

덕분에 원인을 확인 할 수 있었습니다.

원인은

search_list.append({"title": {"$regex": keyword, "$options": "i"}})

이 코드에서 regex 왼쪽에 $를 빼먹어서 문제였습니다.

$를 붙여주니 정상적으로 검색이 되었습니다.

 

새벽에 코드를 타이핑하며 비교를 해보니 아무래도 피곤해서 놓친듯 합니다.

 

감사합니다.

 

남박사님의 프로필 이미지
남박사
지식공유자

안녕하세요, 고양이님.

안그래도 자세한 질문과 환경 및 코드를 주셔서 제가 코드를 직접 실행해서 확인해보려고 하는데 제 몽고디비 도커 컨테이너가 맛이가서 한참을 고민하고 있는데 답변을 달려고 와보니 이미 해결을 하셨네요. 저도 그런 비슷한 문제를 해결하는데 생각보다 많은 시간을 쓸 때가 많습니다. 알고나면 간단한거고 당연한건데 사람인지라 실수를 할때가 있습니다. 그래도 엄청 빨리 찾아서 해결하셨다는게 대단하십니다~!!

호기심고양이님의 프로필 이미지
호기심고양이

작성한 질문수

질문하기