开发者

How do search engines conduct 'AND' operation?

开发者 https://www.devze.com 2022-12-21 03:24 出处:网络
Consider the following search results: Google for \'David\' - 591 millions hits in 0.28 sec Google for \'John\' - 785 millions hits in 0.18 sec

Consider the following search results:

  • Google for 'David' - 591 millions hits in 0.28 sec
  • Google for 'John' - 785 millions hits in 0.18 sec

OK. Pages are indexed, it only needs to look up the count and the first few items in the index table, so speed is understandable.

Now consider the following search with AND operation:

  • Google for 'David John' ('David' AND 'John') - 173 millions hits in 0.25 sec

This makes me ticked ;) How on earth can search engines get the result of AND operations on gigantic datasets so fast? I see the following two ways to conduct the task and both are terrible:

  1. You conduct the search of 'David'. Take the gigantic temp table and conduct a search of 'John'开发者_如何学C on it. HOWEVER, the temp table is not indexed by 'John', so brute force search is needed. That just won't compute within 0.25 sec no matter what HW you have.
  2. Indexing by all possible word combinations like 'David John'. Then we face a combinatorial explosion on the number of keys and not even Google has the storage capacity to handle that.

And you can AND together as many search phrases as you want and you still get answers under a 0.5 sec! How?


What Markus wrote about Google processing the query on many machines in parallel is correct.

In addition, there are information retrieval algorithms that make this job a little bit easier. The classic way to do it is to build an inverted index which consists of postings lists - a list for each term of all the documents that contain that term, in order.

When a query with two terms is searched, conceptually, you would take the postings lists for each of the two terms ('david' and 'john'), and walk along them, looking for documents that are in both lists. If both lists are ordered the same way, this can be done in O(N). Granted, N is still huge, which is why this will be done on hundreds of machines in parallel.

Also, there may be additional tricks. For example, if the highest-ranked documents were placed higher on the lists, then maybe the algorithm could decide that it found the 10 best results without walking the entire lists. It would then guess at the remaining number of results (based on the size of the two lists).


I think you're approaching the problem from the wrong angle.

Google doesn't have a tables/indices on a single machine. Instead they partition their dataset heavily across their servers. Reports indicate that as many as 1000 physical machines are involved in every single query!

With that amount of computing power it's "simply" (used highly ironically) a matter of ensuring that every machine completes their work in fractions of a second.

Reading about Google technology and infrastructure is very inspiring and highly educational. I'd recommend reading up on BigTable, MapReduce and the Google File System.

Google have an archive of their publications available with lots of juicy information about their techologies. This thread on metafilter also provides some insight to the enourmous amount of hardware needed to run a search engine.


I don't know how google does it, but I can tell you how I did it when a client needed something similar:

It starts with an inverted index, as described by Avi. That's just a table listing, for every word in every document, the document id, the word, and a score for the word's relevance in that document. (Another approach is to index each appearance of the word individually along with its position, but that wasn't required in this case.)

From there, it's even simpler than Avi's description - there's no need to do a separate search for each term. Standard database summary operations can easily do that in a single pass:

SELECT document_id, sum(score) total_score, count(score) matches FROM rev_index
WHERE word IN ('david', 'john') GROUP BY document_id HAVING matches = 2
ORDER BY total_score DESC

This will return the IDs of all documents which have scores for both 'David' and 'John' (i.e., both words appear), ordered by some approximation of relevance and will take about the same time to execute regardless of how many or how few terms you're looking for, since IN performance is not affected much by the size of the target set and it's using a simple count to determine whether all terms were matched or not.

Note that this simplistic method just adds the 'David' score and the 'John' score together to determine overall relevance; it doesn't take the order/proximity/etc. of the names into account. Once again, I'm sure that google does factor that into their scores, but my client didn't need it.


I did something similar to this years ago on a 16 bit machine. The dataset had an upper limit of around 110,000 records (it was a cemetery, so finite limit on burials) so I setup a series of bitmaps each containing 128K bits.

The search for "david" resulting in me setting the relevant bit in one of the bitmaps to signify that the record had the word "david" in it. Did the same for 'john' in a second bitmap.

Then all you need to do is a binary 'and' of the two bitmaps, and the resulting bitmap tells you which record numbers had both 'david' and 'john' in them. Quick scan of the resulting bitmap gives you back the list of records that match both terms.

This technique wouldn't work for google though, so consider this my $0.02 worth.

0

精彩评论

暂无评论...
验证码 换一张
取 消