「OR」析取在計費作業和計算時間方面都是高成本的作業。假設您要搜尋 'cuisine:Japanese OR cuisine:Korean',替代方法是為料理類別較籠統的文件建立索引。在這種情況下,查詢可以簡化為 'cuisine:Asian'。
消除查詢中的重言式
假設您要尋找多倫多的所有餐廳,且您的文件僅有一個名為「city」的欄位,如果使用 'city:toronto AND NOT city:montreal' 查詢,將會取得與 'city:toronto' 相同的結果,因為如果將城市設定為 "toronto",就不能設定為 "montreal"。第二個查詢的執行速度會快很多,因為它只涉及一個字詞。第一個查詢會執行三個步驟:首先它會尋找將城市設定為「toronto」的文件清單,然後尋找城市不是設定為「montreal」的所有城市清單,最後計算這兩個清單的交集。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["難以理解","hardToUnderstand","thumb-down"],["資訊或程式碼範例有誤","incorrectInformationOrSampleCode","thumb-down"],["缺少我需要的資訊/範例","missingTheInformationSamplesINeed","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-09-04 (世界標準時間)。"],[[["\u003cp\u003eThis API is designed for first-generation runtimes and is relevant when upgrading to second-generation runtimes, with a migration guide available for those moving to Java 11/17.\u003c/p\u003e\n"],["\u003cp\u003eEfficient batch operations for adding or deleting documents in an index can be done by handling up to 200 documents at once, which is more performant than individual operations.\u003c/p\u003e\n"],["\u003cp\u003eUsing the document rank to pre-sort documents, particularly for frequently used sorting criteria such as price, significantly improves search performance and can eliminate the need for sort options.\u003c/p\u003e\n"],["\u003cp\u003eEmploying atom fields for boolean data and converting negative queries into positive ones enhances search efficiency compared to using number fields or negative logic.\u003c/p\u003e\n"],["\u003cp\u003eMinimizing the use of disjunctions ("OR") and eliminating tautologies within queries, as well as narrowing the document range before sorting, can substantially improve performance and reduce processing time.\u003c/p\u003e\n"]]],[],null,["# Search Best Practices\n\n| This API is supported for first-generation runtimes and can be used when [upgrading to corresponding second-generation runtimes](/appengine/docs/standard/\n| java-gen2\n|\n| /services/access). If you are updating to the App Engine Java 11/17 runtime, refer to the [migration guide](/appengine/migration-center/standard/migrate-to-second-gen/java-differences) to learn about your migration options for legacy bundled services.\n\nThis document describes the best practices for the Search API. We use single\nquotes ('') throughout to delimit query strings. This way a query that contains\nmulti-word phrases surrounded by double quotes can be delimited without confusion:\n`'field:\"some text\" some-value'`.\n\n### Batch Index.put() and Index.delete() calls\n\nYou can pass up to 200 documents at a time when adding or deleting them from an index. This is much more efficient than handling them one at a time.\n\n### Use document rank to pre-sort documents\n\nBy default, search returns its results by descending rank. Also by default, the Search API sets the rank of each document to seconds since Jan 1st 2011. This results in the freshest documents being returned first. However, if you don't need documents to be sorted by the time they were added, you can use rank for other purposes. Suppose you have a real estate application. What customers want most is sorting by price. For an efficient default sort, you could set the rank to the house price.\n\nIf you need multiple sort orders such as price low-to-high and price high-to-low, you can create a separate index for each order. One index would have rank = price and the other rank = MAXINT-price (since rank must be positive).\n\nUsing rank as the sort key will improve search performance. To specify other sort keys, you must use sort options, which limits the number of search results to 10,000 documents. In this case, the sort order determined by rank will determine which documents will be included in the sort. Read about [sort options](/appengine/docs/legacy/standard/java/search/options#SortOptions) to learn more.\n\n### Use atom fields for boolean data\n\nStoring boolean data in number fields is very inefficient. Use atom fields instead, and assign your favorite constants (True/False, yes/no, 0/1).\n\n### Turn negatives into positives\n\nSuppose you have a special term to identify restaurants whose cuisine is undefined. If you want to exclude those restaurants you could use `'NOT cuisine:undefined'` as your query. This is, however, more expensive to evaluate (in both billable operations and computation time) than having the opposite, finding restaurants whose cuisine is known. Rather than having one field, cuisine, you can use two, `cuisine`, and `cuisine_known`, with the latter being an atom field. For restaurants for which cuisine is defined, you set the first field to the actual cuisine and the second field to `\"yes\"`. For restaurants for which you do not know the cuisine, you set cuisine to `\"\"` (an empty string) and `cuisine_known` to `\"no\"`. Now to find restaurants for which cuisine is known you issue a query `'cuisine_known:yes'`, which is much faster than the negation.\n\n### Turn disjunctions into conjunctions\n\nThe \"OR\" disjunction is an expensive operation in both billable operations and computation time. Suppose you want to search for `'cuisine:Japanese OR cuisine:Korean'`. An alternative is to index documents with more general categories of cuisine. In this case, the query may be simplified to `'cuisine:Asian'`.\n\n### Eliminate tautologies from your queries\n\nSuppose you want to find all restaurants in Toronto. Assuming that your documents have only a single field named \"city\", if you use the query `'city:toronto AND NOT city:montreal'` you get the same results as `'city:toronto'`, because if city is set to `\"toronto\"` it cannot be set to `\"montreal\"`. The second query runs much faster since it involves only one term. The first query performs three steps: first, it finds a list of documents where city is set to \"toronto\", then it finds a list of all cities for where city is not set to \"montreal\", and finally it computes the intersection of the two lists.\n\n### Narrow the range before sorting\n\nSuppose your application stores information about restaurants around the world, and you would like to show the restaurants closest to the current user. One way of doing this is to sort matching documents by the distance from the user's location. But if you have 1,000,000 restaurants, running a query like `'cuisine:japanese'` with the sort expression distance(geopoint(x, y), restaurant_loc) will take a long time. It's a good idea to add filters to a query so that you start with a more salient set of selected documents to sort. One solution is to create geographical categories, such as country, state and city - you could infer city and state from the user's location. Then your query becomes `'cuisine:japanese AND city:\u003cuser-city\u003e'`. Chances are very good that you'll no longer need to sort 1,000,000 documents.\n\n### Use narrow categories to avoid or minimize sorting\n\nIf you use rank to sort restaurants by price, you could create a `price_range` field that contains price categories: `price_0_10`, `price_11_20`, `price_21_30`, `price_31_40`, `price_41_lots`. You could then find all restaurants that cost between $21 and $40 with no sorting at all using the query `'price_range:price_21_30 OR price_range:price_31_40'`. In many cases the appropriate categories are not as clear-cut, but with this technique you can reject a large number of documents before winnowing down the search with expensive queries such as `'... AND price\u003e25 AND price\u003c35'`.\n\n### Do not score matches unless you need to\n\nScoring is used to indicate how well a given document matched a query. However, unless you intend to sort by score, do not request scoring. It will only slow down your search."]]