summaryrefslogtreecommitdiff
path: root/bucky/search/search.js
blob: bde1ad9a5f81f49f893e18f157fbaf42a868e72b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
var db = require('../db')
var eachSeries = require('async/eachSeries');
var redisClient = require('./redis-client.js')
const { promisify } = require("util");
const lookupAsync = promisify(redisClient.get).bind(redisClient);
var STOPWORDS = require('./stopwords')

var wordRegexp = new RegExp("[^a-z0-9]+", 'g');
function parse_terms (s) {
  return s.toLowerCase().split(wordRegexp).filter((term) => !!term)
}
function cmp (a,b){ return (a<b)?-1:(a===b)?0:1 }

function split_results(data) {
 if (! data.length) return []
  var matches = data.split(",").map((s) => {
    if (! s.length) return;
    var partz = s.split(" ")
    return {
      thread: parseInt(partz[0]),
      comment: parseInt(partz[1]),
      file: parseInt(partz[2]),
      strength: parseInt(partz[3]) || 1,
    }
  })
  return matches
}

function search (query, start, limit, cb) {
  
  if (!query) return
	start = parseInt(start) || 0;
	limit = parseInt(limit) || 10;
	var scores = {};
	var terms = parse_terms(query);
  var total
  var to_display = limit
  var threads = {}
  var thread_ids = []
  var comment_ids = []
  var file_ids = []
  var results = []


  console.log(terms)
  eachSeries(
    terms, 
    function(term, callback){
      console.log(term);
      if (STOPWORDS.has(term)) return;
      console.log("howdy")
      redisClient.get(term, function(err, results){
//        if (!results) return callback();

        results = split_results(results)
        results.forEach((result) => {
          //this is a reference, mutating scores
          var score = scores[result.thread] = scores[result.thread] || { count: 0, strength: 0 }
          score.thread = score.thread || parseInt(result.thread)
          score.comment = score.comment || parseInt(result.comment)
          score.file = score.file || parseInt(result.file)
          score.strength += parseFloat(result.strength)
          score.count += 1
        })
        callback()
      })
     }, 
    function() {
      total = Object.keys(scores).length
      Object.values(scores).sort((b,a) => {
        return cmp(a.strength, b.strength)
      }).some((match, i) => {
        if (i < start) return false
        if (to_display-- === 0) return true
        results.push(match)
        // console.log(match)
        thread_ids.push(match.thread)
        if (match.comment) comment_ids.push(match.comment)
        if (match.file) file_ids.push(match.file)
        return false
      })
      //console.log(results)
      redisClient.quit()
      cb( {
        meta: {
          query: query,
          terms: terms,
          start: start,
          next: start + limit,
          limit: limit,
          total: total,
        },
        results: results,
        thread_ids: thread_ids,
        comment_ids: comment_ids,
        file_ids: file_ids,
      });
  })

}

module.exports = { search: search }