레이블이 find인 게시물을 표시합니다. 모든 게시물 표시
레이블이 find인 게시물을 표시합니다. 모든 게시물 표시

mongodb-go-driver cursor not found error

# mongo go client v1.9.1 (https://github.com/mongodb/mongo-go-driver) 로 documents 조회(find)를 다음과 같이 구현했다.
cursor, err := c.collection.Find(context.TODO(), filter)
if err != nil {
    return err
}
defer cursor.Close(context.TODO())
return cursor.All(context.TODO(),  results)

# 여러개의 조회 요청이 동시에 들어오면 일부 요청 결과에 다음 에러가 발생했다.
(CursorNotFound) Cursor not found (namespace:

# 에러를 발생하는 mongo-go-driver 부분
# https://github.com/mongodb/mongo-go-driver/blob/4f06ad2489b73cd1dbcebb5e7df09b77cb643be1/mongo/cursor.go#L266

# document 수가 50개로 적은 컬렉션에 대해서 조회시 발생하지 않고,
# document 수가 156개인 컬렉션에서 발생했다.
 
# 커서를 읽기(cursor.All)전에 현재 커서에 있는 document 를 찍어보면 101로 보인다.
cursor.RemainingBatchLength()

# 이유는 default batchSize=101 이기 때문이다.
# 인덱스 없는 정렬시에는 전체 document 를 로딩한다고 한다.
```
find() and aggregate() operations have an initial batch size of 101 documents by default. Subsequent getMore operations issued against the resulting cursor have no default batch size, so they are limited only by the 16 megabyte message size.

For queries that include a sort operation without an index, the server must load all the documents in memory to perform the sort before returning any results.
```

# Find 옵션으로 batch 크기를 다음과 같이 설정했다.
opts := options.Find()
opts = opts.SetBatchSize(500)
cursor, err := c.collection.Find(context.TODO(), filter, opts)

# cursor.RemainingBatchLength()를 출력해보면 156 이다.
# 위와 같이 한번에 전체 documents 를 가져오니 cursor not found 에러가 발생하지 않았다.
# batchSize 가 전체 documents 보다 작으면 계속 batchSize 만큼 조회해서 가져오는것으로 보인다.(실제 batchSize 101일때 1번 find 최종 조회 결과는 156개의데이터를 모두 가져왔다.)
# 하지만 이 과정에서 동시에 조회가 실행될 경우 서버로 부터 커서를 찾을 수 없다는 응답(헤더)를 받는것으로 보인다.

# 참고
# default batchSize 로 인한 지연
# batchSize 설정값에 따른 성능 결과

Linux find 명령 실행시 "paths must precede expression" 에러

find ./ -name *.txt
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

위처럼 find 명령 실행시 "paths must precede expression" 에러를 내는 경우가 있다.
이는 와일드카드(*)를 사용할때 따옴표(')로 묶어 주지 않아서 나는 에러이다.
올바르게 사용하려면 아래와 같이 묶어준다.
find ./ -name '*.txt'

Linux ls find grep sed 를 이용한 유용한 명령들

# 디렉토리 내의 모든 파일들을 대상으로 문자열 찾기
# -r : 재귀수행(하위 디렉토리)
# -n : 라인번호# --include=*.txt : txt 확장자 파일만 대상
# ysoftman : 찾을 문자열
# . : 시작할 디렉토리
grep -rn --include=*.txt ysoftman .

# jpg 파일들만 검색해서 다른 디렉토리로 복사하기
# find . : 현재 디렉토리를 포함한 하위 디렉토리에서
# -name *.jpg : 확장자가 jpg 인 파일을 찾아
# -exec cp -v {}  /home/ysoftman/ \; : 찾은결과 {} 에서 /home/ysoftman 로 -v 복사상태를 표시하며 복사(-exec 는 항상 공백\; 로 끝나야한다.)
find . -name *.jpg -exec cp -v {} /home/ysoftman/ \;

# sed test1
# 하위 디렉토리(파일을 제외)만 출력하기
# ls -lR ./ ysoftman : ./ysoftman 디렉토리에서 -l : 리스트, -R : 하위 디렉토리
# | grep ":$" : 앞의 출력 결과를 파이프로 넘겨받아 : 로 끝나는 부분만 출력
# | sed 's/:/\//' : 앞의 출력 결과를 파이프로 넘겨받아 처음 부분을 [subdir] 로 바꿔서(추가) 출력
ls -lR .. | grep ":$" | sed "s/^/[subdir]/"
# sed_test.txt 내용에서 ysoftman 찾으면 출력 끝내기
cat sed_test.txt | sed "/ysoftman/q"

# sed test2
# 임시 텍스트 파일 생성
TEMP_FILE="sed_test.tmp"
echo 'aaa line1
bbb line2
ccc line3
ddd line4
eee line5
fff line6
ggg line7
hhh line8
iii line9
jjj line10' > ${TEMP_FILE}
# 라인2만 삭제하고 출력
# d 삭제
echo 'delete line 2 and print'
cat ${TEMP_FILE} | sed  "2d;"
# 2~4 라인만 출력
# -n sed 가 입력받은 각라인의 에코 출력하는것을 막는다. 조건에 해당하는것만 출력하도록 한다.
# '2,4p' 2~4라인 프린트2~4라인 프린트
echo 'print only line 2~4'
cat ${TEMP_FILE} | sed -n "2,4p"
# 3~5 7~8 라인만 출력
# ; 는 조건의 끝을 나타낸다.
echo 'print only line 3~5, 7~8'
cat ${TEMP_FILE} | sed -n "3,5p;7,8p;"
# ccc ~ ggg 패턴 사이의 내용 출력
echo 'print only pattern ccc ~ ggg '
cat ${TEMP_FILE} | sed  -n "/^ccc/,/^ggg/p;"
# ccc ~ ggg 패턴 사이의 내용만 삭제하고 출력
echo 'delete pattern ccc ~ ggg and print'
cat ${TEMP_FILE} | sed "/^ccc/,/^ggg/d;"
# 임시 텍스트  파일 삭제
rm -f ${TEMP_FILE}

# sed test3
# @뒤로 삭제
# Substitute 형식 : s/regular expression/replacement/flag
out=`(echo "ysoftman @open (12345)" | sed "s/@.*$//")`
echo "$out"___result
# 공백@ 뒤로 삭제
out=`(echo "ysoftman @open (12345)" | sed "s/ @.*$//")`
echo "$out"___result
# 컬문자의 경우
reset_color='\033[0m'
green='\033[0;32m'
# 공백이 아닌 컬러 문자가 포함되어 공백 뒤 삭제가 안된다.
echo -e "ysoftman ${green}color${reset_color} string " | sed "s/ color.*$//"
# 중간에 컬러 문자를 제거해줘야 한다.
echo -e "ysoftman ${green}color${reset_color} string " | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | sed "s/ color.*$//"