麻烦问一下我这个foreach循环遍历数组写的有问题吗,老是报错:this.totalData.forEach is not a function

{foreach},{foreachelse}
{foreach} 用于像循环访问一个数字索引数组一样循环访问一个关联数组,与仅能访问数字索引数组的{section}不同,{foreach}的语法比 {section}的语法简单得多,但是作为一个折衷方案也仅能用于单个数组。每个{foreach}标记必须与关闭标记{/foreach}成对出现。
1、from&&& 类型:array数组 必要性:Yes必要默认值:n/a&&& 描述:循环访问的数组
2、item&&&& 类型:string字符串&&&& 必要性:Yes必要&&&& 默认值:n/a&&&& 描述:当前元素的变量名
3、key&&&&& 类型:string字符串&&&& 必要性:No可选&&&& 默认值:n/a&&&& 描述:当前键名的变量名
4、name&& 类型:string字符串&&&& 必要性:No可选&&&& 默认值:n/a&&&& 描述:用于访问foreach属性的foreach循环的名称
from和item是必要属性{foreach}循环的name可以是任何字母,数组,下划线的组合,参考PHP变量。{foreach}循环可以嵌套,嵌套的{foreach}的名称应当互不相同。from属性通常是值数组,被用于判断{foreach}的循环次数。在from变量中没有值时,将执行{foreachelse}。{foreach}循环也有自身属性的变量,可以通过{$smarty.foreach.name.property}访问,其中"name"是name属性。注意:name属性仅在需要访问{foreach}属性时有效,与{section}不同。访问未定义name的{foreach}属性不会抛出一个错误,但将导致不可预知的结果。{foreach}属性有index, iteration, first, last, show, total.
例一. item属性&?php$arr = array(, 1002);$smarty-&assign('myArray', $arr);?&
用模板以无序列表输出$myArray
&ul&&&&& {foreach from=$myArray item=foo}&&& &li&{$foo}&/li&&&& {/foreach}&/ul&
上例将输出:
&ul&&&& &li&1000&/li&&&& &li&1001&/li&&&& &li&1002&/li&&/ul&
例二. 演示item和key属性
&?php$arr = array(9 =& 'Tennis', 3 =& 'Swimming', 8 =& 'Coding');$smarty-&assign('myArray', $arr);?&
用模板按键名/键值对的形式输出$myArray, 类似于PHP的foreach。
&ul&&&& {foreach from=$myArray key=k item=v}&& &li&{$k}: {$v}&/li&&&& {/foreach}&/ul&
上例将输出:
&ul&&&& &li&9: Tennis&/li&&&& &li&3: Swimming&/li&&&& &li&8: Coding&/li&&/ul&
例三. {foreach}的item属性是关联数组
&?php$items_list = array(23 =& array('no' =& 2456, 'label' =& 'Salad'),&&&&&&&&&&&&&&&&&&& 96 =& array('no' =& 4889, 'label' =& 'Cream')&&&&&&&&&&&&&&&&&&&& );$smarty-&assign('items', $items_list);?&
模板中,url通过$myId输出$items
&ul&&&& {foreach from=$items key=myId item=i}&& &li&&a href="item.php?id={$myId}"&{$i.no}: {$i.label}&/li&&&& {/foreach}&/ul&
上例将输出:
&ul&&& &li&&a href="item.php?id=23"&2456: Salad&/li&&& &li&&a href="item.php?id=96"&4889: Cream&/li&&/ul&
例四. {foreach}使用嵌套的item和key
向Smarty设置一个数组,对于每个键名对应的每个循环值都包括键。
&?php$smarty-&assign('contacts', array(&&&&&&&&&&&&&&&&&&&&&&&&&&&&& array('phone' =& '1',&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'fax' =& '2',&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'cell' =& '3'),&&&&&&&&&&&&&&&&&&&&&&&&&&&&& array('phone' =& '555-4444',&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'fax' =& '555-3333',&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'cell' =& '760-1234')&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ));?&
用于输出$contact的模板。
{foreach name=outer item=contact from=$contacts}&hr /&{foreach key=key item=item from=$contact}&&& {$key}: {$item}&br /&{/foreach}{/foreach}
上例将输出:
&hr /&phone: 1&br /&fax: 2&br /&cell: 3&br /&&hr /&phone: 555-4444&br /&fax: 555-3333&br /&cell: 760-1234&br /&
例五. 使用{foreachelse}的数据库示例
一个数据库(例如PEAR或ADODB)的搜索脚本示例,
&?php&& $search_condition = "where name like '$foo%' ";$sql = 'select contact_id, name, nick from contacts '.$search_condition.' order by name';$smarty-&assign('results', $db-&getAssoc($sql) );?&
借助{foreachelse}标记在没有结果时模板输出"None found"字样。
{foreach key=cid item=con from=$results}&&& &a href="contact.php?contact_id={$cid}"&{$con.name} - {$con.nick}&/a&&br /&{foreachelse}&&& No items were found in the search{/foreach}.index包含当前数组索引,从零开始。
例六. index示例
{* 每五行输出一次头部区块 *}&table&{foreach from=$items key=myId item=i name=foo}&& {if $smarty.foreach.foo.index % 5 == 0}&&&&& &tr&&th&Title&/th&&/tr&&& {/if}&& &tr&&td&{$i.label}&/td&&/tr&{/foreach}&/table&&&iteration包含当前循环次数,与index不同,从1开始,每次循环增长1。
例七. iteration和index示例
{* this will output 0|1, 1|2, 2|3, ... etc *}{* 该例将输出0|1, 1|2, 2|3, ... 等等 *}{foreach from=$myArray item=i name=foo}{$smarty.foreach.foo.index}|{$smarty.foreach.foo.iteration},{/foreach}&&first在当前{foreach}循环处于初始位置时值为TRUE。
例八. first属性示例
{* 对于第一个条目显示LATEST而不是id *}&table&{foreach from=$items key=myId item=i name=foo}&tr&&& &td&{if $smarty.foreach.foo.first}LATEST{else}{$myId}{/if}&/td&&& &td&{$i.label}&/td&&/tr&{/foreach}&/table&&&last在当前{foreach}循环处于最终位置是值为TRUE。
例九. last属性示例
{* 在列表结束时增加一个水平标记 *}){foreach from=$items key=part_id item=prod name=products}&& &a href="#{$part_id}"&{$prod}&/a&{if $smarty.foreach.products.last}&hr&{else},{/if}{foreachelse}&& ... content ...{/foreach}&&show是{foreach}的参数. show是一个布尔值。如果值为FALSE,{foreach}将不被显示。如果有对应的{foreachelse},将被显示。
total包括{foreach}将循环的次数,既可以在{foreach}中使用,也可以在之后使用。
例十. total属性示例
{* 在结束位置显示行数 *}{foreach from=$items key=part_id item=prod name=foo}{$prod.name&&hr/&{if $smarty.foreach.foo.last}&& &div id="total"&{$smarty.foreach.foo.total} items&/div&{/if}{foreachelse}... something else ...{/foreach}
{foreach from=$custid item=curr_id key=num}&& {if num is odd}&& && &&& 干啥&& {else}&& && && 干其他的&& {/if}{/foreach}与以下的代码的区别,odd和enen的意义?{foreach from=$custid item=curr_id key=num}&& {if num%2==0}&& && &&& 干啥&& {else}&& && && 干其他的&& {/if}{/foreach}
阅读(...) 评论()There was an error loading this resource. Please try again later.WinDbg cheat sheet & The Art of Dev
Working with WinDbg is kind of pain in the ass and I never remember all the commands by heart, so I write down the commands I used.
Loading stuff
.loadby sos mscorwks
Load SOS extension (will identify sos location by loaded mscorwks path)
.load c:\Windows\Microsoft.NET\Framework\v2.0.50727\sos
Load SOS extension for
.load psscor2
Load PSSCOR for .NET 2.0 (replaces SOS)
.load sosex
Load SOSEX extension
.load sieextpub
Load SieExtPub extension
.load rpcexts
Load RPC extension
Unload extension
.cordll -ve -u -l
Retry loading of SOS
!help &command&
Latest extension commands help (SOS,SOSEX,PSSCOR)
!sosex.help
Like !help but for specifically for SOSEX
!sosexhelp
Display this screen or details about the specified command (SOSEX)
!sym noisy
[.symfix c:\symbols]
Load symbols if not set in environment
.load wow64exts
Switched to 32bit mode after doing this
Examining code and stacks
~&thread id&s
Set active thread
all threads
!clrstack [-a] [-p] [-l]
managed call stack (no CLR stuff)
!dumpstack [-ee]
unmanaged and managed call stack
!eestack -short [-ee]
Run dumpstack on all threads and show only ‘interesting’ (lock, hijacked, managed)
!mk [FrameCount] [-l] [-p] [-a]
unmanaged and managed call stack, better than !dumpheap (sosex)
Kb [number]
Unmanaged stack with arguments (kb4 limits stack to 4 frames)
!uniqstack
Unmanaged stacks without duplication, nice if have many worker threads
!threads [-live] [-special]
all managed threads
!dso [-verify] [top stack [bottom stack]]
Objects stack trace (the actual object type and not where the method is)
!mdso [/a | /r | /c:n | /t:&typeFilter& | /mt:&mt&]
Dumps object references on the stack and in CPU registers in the current context
!name2ee mscorlib.dll System.Threading.Thread
.foreach (t {!dumpheap -mt &mtaddress& -short}) {.if(poi(${t}+28)&0){.printf ” Thread Obj: %N, Obj Address: ${t}, Name: %N \n”,poi(${t}+28), poi(${t}+c)}}
2 commands
get the .net threads object address for each thread matching by thread obj id
Exceptions
!analyze -v [-hang]
-v Very detailed exception data (SLOW),
-hang Generates !analyze hung-application output.
!pe [&exceptionAddr&]
most recent exception data (don’t forget the external stack)
Dump all exception found (psscor)
CLR data structures
!eeheap -gc
Get managed heap size
!dumpheap [-stat] [-mt &&] [-type &&] [-strings] [-min] [-max]
What classes take space in managed heap
!dumpheap &address& &address&
Show the object that are in the given memory segments (show only specific generation by combining with output of !eeheap -gc)
!dumpgen &genNum& [-free] [-stat] [-type &&] [-nostrings]
Dumps the contents of the specified generation (sosex)
!gcgen &objectAddr&
Displays the GC generation of the specified object (sosex)
!gcroot &objectAddr& [-nostacks]
Find how an object reference is reachable
!refs &objectAddr& [-target|-source]
Displays all references from and to the specified object (sosex)
!finalizequeue
all the object that are in finalize queue
!finq [genNum] [-stat]
Displays objects in the finalization queue (sosex)
!frq [-stat]
Display objects in the Freachable queue (sosex)
!dumpdomain
Display app-domains info
!FindAppDomain &address&
Determines the application domain of an object at the specified address.
!mx &Filter String&
Displays managed type/field/method names matching the specified filter string (sosex)
!gchandles
List GC handles statistics
!gch [-handleType]
Lists all GC Handles, optionally filtered by specified handle types
Unmanaged Memory
gflags /i &pocess name& +ust
Add allocation stack for this process
!address -summary
Show summery of memory by types
Show all heaps
!heap -stat -h &heap addr&
Show blocks of specific heap
!heap -flt s &block size&
Show addresses of memory blocks of specific size by heap
!heap -p -a &usrPtr&
Display allocation call stack for given block user ptr address
Object Inspection
!do &address&
information about object
!dumpvc &mt& &address&
Information about struct
!mdt [typename | MT] [addr] [-r[:level]] [-e[:level]]
Displays the fields of an object or type, -r optionally recursively, -e optionally collections (sosex)
!mroot &addr&
Displays GC roots for the specified object (sosex)
!objsize &addr&
The size of the object including all fields
!dumpmt -md &addr&
see what methods the object exposes (preJiv – ngen, Jit – jitted, None
– never been called)
!name2ee * &type name&
Get the class data for specific type
!da &addr& [-start #] [-length #] [-details]
Displays the contents of an array at the address 00ad28d0. starts from the second element and continues for five elements.
!refs &addr& [-target|-source]
Displays all references from and to the specified object (sosex)
!syncblk [-all | &syncblkNumber&]
Show all sync blocks that are owned by the current thread but not thinlocks, use !DumpHeap -thinlock
!DumpHeap -thinlock
Show all the thin locks
Displays deadlocks between SyncBlocks and/or ReaderWriterLocks, only managed (sosex)
Get critical sections that threads are locked on (sieextpub)
!mlocks [-d]
Lists all managed lock objects and CriticalSections and their owning threads (sosex)
!mwaits [-d]
Lists all waiting threads and, if known, the locks they are waiting on (sosex)
!rwlock [objectAddr | -nd]
Displays all RWLocks or, if provided a RWLock address, details of the specified lock (sosex)
dt &lockAddr&
!handle &handleAddr& f
Show data on the handle, if mutex or event can show the owner (procId.ThreadId)
Clear screen
~*e &command&
Execute command for all threads
!u, u &method intptr&
Show the disassemble of a method
!mu [addr] [-s] [-il] [-n]
Displays a disassembly around the current instruction with interleaved source, IL and asm code (sosex)
!muf [MD| Code Addr] [-s] [-il] [-n]
Displays a disassembly with interleaved source, IL and asm code (sosex)
!dumpil &method intptr&
Show the IL code of the method
!address &address&
displays information about the memory that the target process or target computer uses.
CPU time of each thread
sxe ld:&dll name&
why a specific module was loaded
The time of the dump
Crazy loops
poi(&address&)
Follow reference for the given pointer (handle) address
!SaveModule &addr& &path&
Save the module dll to a file (can be used to get its version)
!TraverseHeap [-xml] &filename&
Dump heap data that can be used by CLR profiler
displays all elements of the TEB or “Thread Environment Block”
!strings [ModuleAddress] [min] [max] [gen#] [filter]
Search the managed heap or a module for strings matching the specified criteria
!mln &addr&
Displays the type of managed data located at the specified address or the current instruction pointer
lm [v] [m] &moduleName&
Show data on the loaded modules (mscorwks, clr)
list loaded modules with full path
Show version and paths of all loaded modules (sieextpub)
Show COM calls on all threads
!rpcreadstack &stack addr&
Get RPC call information (rpcexts)
!getendpointinfo &port&
searches the system’s RPC state information for endpoint information (rpcexts)
Advertisements
Share this:Like this:Like Loading...
nice set of commands.. very useful to me. Thanks.
Connecting to %s
Advertisements
%d bloggers like this:A practical comparison of Map-Reduce in MongoDB and RavenDB
Over the past week I've been learning about . In my adventures with Node.js I am now at the point where I need some kind of data store.
I've found MongoDB fairly easy to grasp due to their
and that I have experience with . Therefore many of the concepts surrounding NoSQL/Document databases are already familiar to me.
I thought it would be interesting to do a practical comparison of Map-Reduce in both MongoDB and RavenDB.
To begin with I created a bunch of "blog post" documents in both database with the following structure:
"title" : "ASP.NET Identity Stripped Bare - MVC",
"tags" : [
"ASP.NET",
"ASP.NET MVC",
"Security"
The goal is to use Map-Reduce to generate a list of tags with a count of their usage e.g.
"tag" : "DDD",
"count" : 1,
"tag" : "OWIN",
"count" : 2,
"tag" : "Security",
"count" : 1,
We could use this data to generate something fancy like a tag cloud on a web site (like it's 2005 baby).
One of my favourite things about MongoDB so far is the JavaScript API and hacking away in the mongo shell. Using a dynamic language for unstructured/dynamic data is quite advantageous.
Map-Reduce (JavaScript API)
To begin with I
one for map and one for reduce.
The map function projects (or emits) each tag:
var map = function() {
this.tags.forEach(function(tag) {
emit(tag, {
emit takes a key (used to reduce the data) and a value.
It's important to note that MongoDB only calls the reduce function for those keys that have multiple values. Therefore the value you emit should mirror the return value from the reduce function.
This through me at first as I did not understand why I was not getting any data back for tags that have only been used once and is the reason why I emit count: 1 above.
The reduce function aggregates the results and is called for each unique key in the result set:
var reduce = function(key, values) {
var totalCount = 0;
values.forEach(function(value) {
totalCount++;
count: totalCount
To execute the Map-Reduce function and output to the shell we call:
db.posts.mapReduce(map, reduce, { out: { inline: 1 }})
This produces the following results:
"results" : [
"_id" : "OWIN",
"value" : {
"count" : 3
"_id" : "Security",
"value" : {
"count" : 1
"_id" : "foo",
"value" : {
"count" : 1
"_id" : "jQuery",
"value" : {
"count" : 2
"timeMillis" : 35,
"counts" : {
"input" : 8,
"emit" : 13,
"reduce" : 2,
"output" : 10
Notice that we also get some stats about the Map-Reduce operation such as the number of documents emitted, how many were reduced and how many were output.
To store the results in a collection we execute:
db.posts.mapReduce(map, reduce, { out: 'post_tags' })
Now I can query the results, for example sorting by tag name:
db.post_tags.find().sort({ _id: 1 })
Something that caught me out (again because I'm used to RavenDB) is that MongoDB performs case sensitive sorting so I actually end up with:
Instead of:
The solution (it seems) is to store a lowercase version of each tag and use that as a sort key. Fortunately we can use a
function (a bit like TransformResults in RavenDB) to add this to the final results:
var finalize = function(key, reducedValue) {
reducedValue.sort_key = key.toLowerCase();
return reducedV
Unlike reduce, finalize is called for every key (not just those keys that have multiple values). To execute the Map-Reduce and use the finalize function we call:
db.posts.mapReduce(map, reduce, { out: 'post_tags', finalize: finalize })
Now we can sort on sort_key and get the expected results:
db.post_tags.find().sort({ 'value.sort_key': 1 })
Another way of achieving the same thing without finalize is make the sort key part of the key:
var map = function() {
this.tags.forEach(function(tag) {
emit({ tag: tag, sort_key: tag.toLowerCase() }, {
db.post_tags.find().sort({ '_id.sort_key': 1 })
Using the Aggregation Pipeline
The MongoDB docs recommend using the
for most aggregation operations. Map-Reduce offers slightly more flexibility since you can do whatever you like within the map and reduce functions whereas aggregate is limited to the provided operators. That said it is a powerful feature.
The input documents are passed through each stage in the pipeline. There are built in operators for projection, grouping and sorting to name a few.
To achieve our tag summary we execute the following pipeline:
db.posts.aggregate(
$project: {
count: { $add: 1 }
$unwind: '$tags'
tag: '$tags', sort_key: { $toLower : '$tags' } },
$sum: '$count'
The $project operator projects a result containing just the tags of each post. If we were to execute just this stage of the pipeline we would get something like:
"_id" : ObjectId("532c320bb07ab5aace243c8d"),
"tags" : [
"ASP.NET",
"ASP.NET MVC",
"Security"
"_id" : ObjectId("532c323bb07ab5aace243c8e"),
"tags" : [
"_id" : ObjectId("532caace243c8f"),
"tags" : [
We're using the $count operator to $add our count of 1 into the result set for each tag.
Next $unwind effectively unwinds the tags array so an array of three tags would produce three separate documents. For example, attaching this step into the pipeline:
"_id" : ObjectId("532c320bb07ab5aace243c8d"),
"tags" : "ASP.NET"
"_id" : ObjectId("532c320bb07ab5aace243c8d"),
"tags" : "ASP.NET MVC"
"_id" : ObjectId("532c320bb07ab5aace243c8d"),
"tags" : "Security"
"_id" : ObjectId("532c323bb07ab5aace243c8e"),
"tags" : "jQuery"
"_id" : ObjectId("532c323bb07ab5aace243c8e"),
"tags" : "foo"
Finally, we use $group to group the results by the tag name. We also store the lowercase sort key in the group's _id:
"tag" : "ASP.NET MVC",
"sort_key" : "asp.net mvc"
"count" : 1
"tag" : "jQuery",
"sort_key" : "jquery"
"count" : 2
Currently there is not a way to save the results within the aggregation pipeline (MongoDB 2.6.x will provide the $out operator) so you would need to store the results in a variable and then manually add them to a collection.
Using the C# Driver
After using the JavaScript API, the C# driver felt like a step backwards. This isn't to say that it is bad, it's just it is 1) not as flexible as the JavaScript API (really down to C# being a static language) and 2) not as mature as RavenDB's .NET API.
Point 2 is understandable since RavenDB's primary market is .NET developers and so that would have been a big factor in the design of their API.
After installing the mongocsharpdriver package using NuGet I've created the following class to encapsulate my connection logic and expose the posts collection:
public class MongoContext
private readonly MongoD
public MongoContext()
RegisterConventions();
var client = new MongoClient("mongodb://10.211.55.12");
MongoServer server = client.GetServer();
db = server.GetDatabase("mongodemo");
private void RegisterConventions()
var pack = new ConventionPack();
pack.Add(new CamelCaseElementNameConvention());
ConventionRegistry.Register("camel case",
t =& t.FullName.StartsWith("MongoDBDemo"));
public MongoCollection&Post& Posts
return db.GetCollection&Post&("posts");
The conventions are necessary so that we can map the camel-cased property names in the database to our pascal-cased C# properties. I've defined the following class to represent a blog post:
public class Post
public ObjectId Id { }
public string Title { }
public string[] Tags { }
Querying is similar to the JavaScript API:
foreach (var post in ctx.Posts.FindAll().SetSortOrder("title"))
Console.WriteLine(post.Title);
Things fall down a bit when it comes to Map-Reduce as we have to provide JavaScript Map/Reduce functions as string variables:
var map = new BsonJavaScript(
function() {
this.tags.forEach(function(tag) {
emit({ tag: tag, sort_key: tag.toLowerCase() }, {
var reduce = new BsonJavaScript(
function(key, values) {
var totalCount = 0;
values.forEach(function(value) {
totalCount++;
count: totalCount
var results = ctx.Posts.MapReduce(map, reduce);
foreach (var result in results.GetResults())
Console.WriteLine(result);
Things are marginally better with aggregate but really the static nature of C# just makes what works so well with JavaScript a bit verbose:
var project = new BsonDocument
"$project", new BsonDocument {
{ "tags", 1},
{ "count", new BsonDocument { { "$add", 1} }}
var unwind = new BsonDocument
{ "$unwind", "$tags" }
var pipeline = new[] { project, unwind };
var aggregate = ctx.Posts.Aggregate(pipeline);
foreach (var result in aggregate.ResultDocuments)
Console.WriteLine(result);
In RavenDB you create indexes to perform Map-Reduce. Map and reduce functions are specified in the form of LINQ expressions. Indexes can be created in your code and initialised when your application starts or directly within RavenDB studio:
public class Post_Tags : AbstractIndexCreationTask&Post, Post_Tags.ReduceResult&
public Post_Tags()
Map = posts =& from post in posts
from tag in post.Tags
select new
Tag = tag,
Reduce = results =& from result in results
group result by result.Tag into g
select new
Tag = g.Key,
Count = g.Sum(t =& t.Count)
public class ReduceResult
public string Tag { }
public int Count { }
In the Map function we loop through each post and project each tag with a count of 1. The Map function returns a collection of ReduceResult. The Reduce function then groups these results by Tag produces the total count.
The code below demonstrates how to initialise the store, initialise the index and then query it:
var store = new DocumentStore
Url = "http://localhost:8080",
DefaultDatabase = "ravendemo"
store.Initialize();
store.DatabaseCommands.EnsureDatabaseExists("ravendemo");
IndexCreation.CreateIndexes(Assembly.GetExecutingAssembly(), store);
using (var session = store.OpenSession())
foreach (var result in session.Query&Post_Tags.ReduceResult, Post_Tags&()
.OrderBy(t =& t.Tag))
Console.WriteLine(result.Tag + " " + result.Count);
For me this API is quite a bit easier to work with and test. Again this comes down to the fact that RavenDB was largely designed for .NET, MongoDB was not.
Map-Reduce updates
When you perform Map-Reduce or aggregation in MongoDB the input is effectively a snapshot of the data at that time.
If your data changes it is down to you to perform the Map-Reduce/aggregation again (ideally in a background process).
Rather than having to re-process all of your data, MongoDB enables you to perform
using a query to process "new" data only:
db.sessions.mapReduce(
mapFunction,
reduceFunction,
query: { ts: { $gt: ISODate(' 00:00:00') } },
out: { reduce: "session_stat" },
finalize: finalizeFunction
Unfortunately how to perform the update isn' it's knowing when to do it.
Since MongoDB doesn't provide triggers of any kind (e.g. for when a collection changes) you'd need to handle this in your application (re-execute the Map-Reduce when a post is added/updated).
It seems it is possible to use MongoDB's Oplog as a notification mechanism but it doesn't appear to be a trivial task and you would still need to perform this processing in your own background task.
RavenDB on the other hand performs index updates automatically. So if I add/update a post, the index will be updated. This I believe is a massive plus point, especially when you have data that changes sporadically or a large number of indexes to maintain.
Share this post:
I'm a software engineer and aspiring entrepreneur with 12+ years experience in the tech industry and have worked with startups and SMB’s in areas such as healthcare, recruitment and e-commerce (I even worked in enterprise, once). I founded my first startup
I now head up the engineering team at . If you're interested in working in an exciting and innovative fin-tech company, .

我要回帖

更多关于 foreach循环 的文章

 

随机推荐