[노트] Google Zoekt 코드 검색엔진 코드 브로셔

OpenGrok의 인덱스는 정말 사용하기 어려워요. 루틴을 사용했지만 TD에 머물렀어요.IDF에서 검색어의 일부분은 결과가 없기 때문에 SourceGraph로 이동합니다.SourceGraph는 language 서버 점프 정확도가 놀랄 정도로 낮지 않습니다.그럼 검색 기능만 갖고 싶은데 어떡하지?SourceGraph의 컨테이너 ps 에 들어가서 구글의 아마추어 프로젝트 zoekt 를 사용한 것을 발견했다.코드도 많지 않고 tri-gram 코드에서 ' + 'test'와 같은 문자열을 정확하게 검색할 수 있다.과감하게 포크했어.(기사는 부정기적으로 업데이트됩니다.)
내 포크:https://github.com/dna2fork/zoekt Google:https://github.com/google/zoekt
Json 출력 지원
우선 첫 번째로 해결해야 할 것은 Json을 출력하는 문제입니다. 어떻게 Joekt가 결과를 json의 형식에 따라 출력할 수 있습니까?기본적으로 html입니다.우리는 원본 코드 아래./web/templates.go 아래에 많은 html 모델이 있는 것을 찾았다.코드를 찾아서 읽으면 zoekt-webserver 시작할 때 폴더에 템플릿 파일을 넣을 수 있습니다.흥미진진하게 json의 모형을 하나 썼는데, 올려놓으니 괜찮다. 바로work다.근데 가끔은 계속 틀려서... 제이슨 포맷이 안 맞아?원래 특수한 json의 제어 문자가 있을 때 출력이 혼란스러워졌기 때문에 출력된 문자열을 미리 포맷하는 방법을 강구해야 한다../web/server.go에 Json을 전문적으로 처리하는 함수를 추가하고template에서 이 함수format 데이터를 사용할 수 있습니다~
+       "JsonText": func(json string) string {
+               json = strings.Replace(json, "\\", "\", -1)
+               json = strings.Replace(json, "
", " ", -1) + json = strings.Replace(json, "\r", " ", -1) + json = strings.Replace(json, "\t", "", -1) + return json + },

여러 repo 검색 지원
두 번째 해결책은 조kt를 사용할 때 r:...로 여러 개의 리포를 동시에 검색할 수 없고 한 개만 검색할 수 있다는 것이다. 이것은 매우 짜증스럽다.어떻게 일하는지 봅시다.우선 파라셀을 검색하고 matcher를 검색하고 sorter를 검색하세요.그래서 본다./query/parse.go
	case tokRepo:
		expr = &Repo{Pattern: text}

이것은 r:...를 하나의 표현식으로 바꾸는 node입니다. 이것Repo./query/query.go에 정의되어 있습니다. 어디에 쓰는지 다시 확인하세요--./eval.go
if r, ok := q.(*query.Repo); ok {
	return &query.Const{Value: strings.Contains(d.repoMetaData.Name, r.Pattern)}
}

그 다음에 r:에 있는 문자열이 리포 이름에 포함되었는지 직접 판단한다.간단해. 이 Pattern을stringlist로 생각하면 되잖아. 먼저 split을 하고 각 split 뒤의 부분이 포함되는지 판단하고 하나만 포함되면true를 가.일파를 직접 바꾸다.
func buildRepoListPattern(qStr string) ([]string, error) {
	// TODO: validate qStr (length, split(',') length) if too long return error
	if len(qStr) == 0 {
		return nil, nil
	}
	patterns := strings.Split(qStr, ",")
	return patterns, nil
}

func matchRepoListPattern(name string, patternList []string) bool {
	if (patternList == nil) {
		return true
	}
	if (len(patternList) == 0) {
		return true
	}
	for _, a := range patternList {
		if strings.Contains(name, a) {
			 return true
		}
  }
  return false
}

func (d *indexData) simplify(in query.Q) query.Q {
	eval := query.Map(in, func(q query.Q) query.Q {
		if r, ok := q.(*query.Repo); ok {
			// original: return &query.Const{Value: strings.Contains(d.repoMetaData.Name, r.Pattern)}
			if r.RepoNamesFromPattern == nil {
				r.RepoNamesFromPattern, _ = buildRepoListPattern(r.Pattern)
			}
			return &query.Const{Value: matchRepoListPattern(d.repoMetaData.Name, r.RepoNamesFromPattern)}
		}
		if l, ok := q.(*query.Language); ok {
			_, has := d.metaData.LanguageMap[l.Language]
			if !has {
				return &query.Const{Value: false}
			}
		}
		return q
	})
	return query.Simplify(eval)
}

컴파일, 리셋, 됐어. 더 많은 리포를 검색할 수 있어.
J.Y.Liu 2020.01.06

좋은 웹페이지 즐겨찾기